Merge pull request #23 from TouchInstinct/feature/swift_3

Feature/swift 3
This commit is contained in:
Ivan Smolin 2016-10-10 15:23:49 +04:00 committed by GitHub
commit be3f5abf79
56 changed files with 906 additions and 1363 deletions

View File

@ -1,5 +1,5 @@
github "CocoaLumberjack/CocoaLumberjack" ~> 2.2
github "ReactiveX/RxSwift" ~> 2.6
github "lyft/mapper" ~> 3.0
github "Alamofire/Alamofire" ~> 3.4
github "RxSwiftCommunity/RxAlamofire" ~> 1.1
github "CocoaLumberjack/CocoaLumberjack" ~> 3.0.0
github "ReactiveX/RxSwift" "3.0.0-beta.1"
github "lyft/mapper" "5.0.0-beta.2"
github "Alamofire/Alamofire" ~> 4.0.0
github "RxSwiftCommunity/RxAlamofire" "3.0.0-beta.1"

View File

@ -1,5 +1,5 @@
github "Alamofire/Alamofire" "3.4.1"
github "CocoaLumberjack/CocoaLumberjack" "2.3.0"
github "ReactiveX/RxSwift" "2.6.0"
github "lyft/mapper" "3.0.0"
github "RxSwiftCommunity/RxAlamofire" "1.2"
github "Alamofire/Alamofire" "4.0.1"
github "CocoaLumberjack/CocoaLumberjack" "3.0.0"
github "ReactiveX/RxSwift" "3.0.0-beta.1"
github "lyft/mapper" "5.0.0-beta.2"
github "RxSwiftCommunity/RxAlamofire" "3.0.0-beta.1"

View File

@ -15,5 +15,5 @@ Pod::Spec.new do |s|
s.dependency "RxSwift", '~> 2.6'
s.dependency "RxCocoa", '~> 2.6'
s.dependency "Alamofire", '~> 3.4'
s.dependency "RxAlamofire", '~> 1.1'
s.dependency "RxAlamofire", '~> 2.5'
end

View File

@ -7,33 +7,34 @@
objects = {
/* Begin PBXBuildFile section */
0A3BB96F1D5DCFE100B03CBD /* CocoaLumberjack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3BB96B1D5DCFE100B03CBD /* CocoaLumberjack.framework */; };
0A3BB9701D5DCFE100B03CBD /* Mapper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3BB96C1D5DCFE100B03CBD /* Mapper.framework */; };
0A3BB9711D5DCFE100B03CBD /* RxAlamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3BB96D1D5DCFE100B03CBD /* RxAlamofire.framework */; };
0A3BB9721D5DCFE100B03CBD /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3BB96E1D5DCFE100B03CBD /* RxSwift.framework */; };
0A3BB9741D5DCFEC00B03CBD /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3BB9731D5DCFEC00B03CBD /* RxCocoa.framework */; };
78011A641D47ABC500EA16A2 /* UIView+DefaultReuseIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78011A631D47ABC500EA16A2 /* UIView+DefaultReuseIdentifier.swift */; };
78011A691D47AF5100EA16A2 /* CellCreationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78011A681D47AF5100EA16A2 /* CellCreationType.swift */; };
78011AB31D48B53600EA16A2 /* ApiRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78011AB21D48B53600EA16A2 /* ApiRequestParameters.swift */; };
7824CA521CFEE6B700D7B132 /* UIImage+RenderTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7824CA511CFEE6B700D7B132 /* UIImage+RenderTemplate.swift */; };
780D23431DA412470084620D /* CGImage+Alpha.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D23421DA412470084620D /* CGImage+Alpha.swift */; };
780D23461DA416F80084620D /* CGContext+Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D23451DA416F80084620D /* CGContext+Initializers.swift */; };
7837F60F1CBCF5C0000D74C1 /* EstimatedViewHeightProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7837F60E1CBCF5C0000D74C1 /* EstimatedViewHeightProtocol.swift */; };
785C33451CFC908800C4C4AA /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 785C33441CFC908800C4C4AA /* TableViewController.swift */; };
786A17A11CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786A17A01CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift */; };
786D78E81D53C378006B2CEA /* AlamofireRequest+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786D78E71D53C378006B2CEA /* AlamofireRequest+Extensions.swift */; };
786D78EA1D53C43E006B2CEA /* ApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786D78E91D53C43E006B2CEA /* ApiError.swift */; };
786D78EC1D53C46E006B2CEA /* AlamofireManager+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786D78EB1D53C46E006B2CEA /* AlamofireManager+Extensions.swift */; };
787682FA1CAD40C300532AB3 /* StaticEstimatedViewHeightProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787682F91CAD40C200532AB3 /* StaticEstimatedViewHeightProtocol.swift */; };
787783631CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783621CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift */; };
787783631CA03CA0001CDC9B /* IndexPath+ImmutableIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783621CA03CA0001CDC9B /* IndexPath+ImmutableIndexPath.swift */; };
787783671CA04D4A001CDC9B /* String+SizeCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */; };
787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787A07191D085750009EC97F /* CellsControllerProtocol.swift */; };
788EC15A1CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 788EC1591CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift */; };
78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */; };
78B036411DA4D7060021D5CC /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B036401DA4D7060021D5CC /* UIImage+Extensions.swift */; };
78B036431DA4FEC90021D5CC /* CGImage+Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B036421DA4FEC90021D5CC /* CGImage+Transform.swift */; };
78B036451DA561D00021D5CC /* CGImage+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B036441DA561D00021D5CC /* CGImage+Utils.swift */; };
78B036471DA5624D0021D5CC /* CGImage+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B036461DA5624D0021D5CC /* CGImage+Creation.swift */; };
78B036491DA562C30021D5CC /* CGImage+Template.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B036481DA562C30021D5CC /* CGImage+Template.swift */; };
78B0364B1DA61EDE0021D5CC /* CGImage+Crop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0364A1DA61EDE0021D5CC /* CGImage+Crop.swift */; };
78B0365E1DA624C10021D5CC /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B036581DA624C10021D5CC /* Alamofire.framework */; };
78B0365F1DA624C10021D5CC /* CocoaLumberjack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B036591DA624C10021D5CC /* CocoaLumberjack.framework */; };
78B036601DA624C10021D5CC /* Mapper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B0365A1DA624C10021D5CC /* Mapper.framework */; };
78B036611DA624C10021D5CC /* RxAlamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B0365B1DA624C10021D5CC /* RxAlamofire.framework */; };
78B036621DA624C10021D5CC /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B0365C1DA624C10021D5CC /* RxCocoa.framework */; };
78B036631DA624C10021D5CC /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78B0365D1DA624C10021D5CC /* RxSwift.framework */; };
78B0FC7D1C6B2BE200358B64 /* LogFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */; };
78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7E1C6B2C4D00358B64 /* Log.swift */; };
78B0FC811C6B2CD500358B64 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC801C6B2CD500358B64 /* App.swift */; };
78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */; };
78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */; };
78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */; };
78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */; };
78C36F811D8021DD00E7EBEA /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F801D8021DD00E7EBEA /* UIColor+Hex.swift */; };
78CFEE2E1C5C456B00F50370 /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CFEE2D1C5C456B00F50370 /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -49,14 +50,8 @@
78CFEE591C5C45E500F50370 /* StoryboardIdentifierProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE4E1C5C45E500F50370 /* StoryboardIdentifierProtocol.swift */; };
78CFEE5A1C5C45E500F50370 /* ViewHeightProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE4F1C5C45E500F50370 /* ViewHeightProtocol.swift */; };
78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */; };
78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */; };
78E59B1B1C77470A00C6BFE9 /* ViewsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E59B1A1C77470A00C6BFE9 /* ViewsGenerator.swift */; };
95B39A781D9BFCC30057BD54 /* UIImageView+LoadingImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A771D9BFCC30057BD54 /* UIImageView+LoadingImage.swift */; };
95B39A7A1D9BFD550057BD54 /* UIImage+Loading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A791D9BFD550057BD54 /* UIImage+Loading.swift */; };
95B39A7C1D9C05260057BD54 /* UIImage+Gradients.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A7B1D9C05260057BD54 /* UIImage+Gradients.swift */; };
95B39A7E1D9C069B0057BD54 /* UIImage+Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A7D1D9C069B0057BD54 /* UIImage+Text.swift */; };
95B39A801D9C09440057BD54 /* UIImage+Cropping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A7F1D9C09440057BD54 /* UIImage+Cropping.swift */; };
95B39A841D9C0C3E0057BD54 /* UIImage+Alpha.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A831D9C0C3E0057BD54 /* UIImage+Alpha.swift */; };
78D4B5461DA64D49005B0764 /* UIViewController+DefaultStoryboardIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78D4B5451DA64D49005B0764 /* UIViewController+DefaultStoryboardIdentifier.swift */; };
78D4B54A1DA64EAB005B0764 /* Any+TypeName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78D4B5491DA64EAB005B0764 /* Any+TypeName.swift */; };
95B39A861D9D51250057BD54 /* String+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A851D9D51250057BD54 /* String+Localization.swift */; };
/* End PBXBuildFile section */
@ -71,33 +66,34 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0A3BB96B1D5DCFE100B03CBD /* CocoaLumberjack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CocoaLumberjack.framework; sourceTree = "<group>"; };
0A3BB96C1D5DCFE100B03CBD /* Mapper.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mapper.framework; sourceTree = "<group>"; };
0A3BB96D1D5DCFE100B03CBD /* RxAlamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxAlamofire.framework; sourceTree = "<group>"; };
0A3BB96E1D5DCFE100B03CBD /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxSwift.framework; sourceTree = "<group>"; };
0A3BB9731D5DCFEC00B03CBD /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxCocoa.framework; sourceTree = "<group>"; };
78011A631D47ABC500EA16A2 /* UIView+DefaultReuseIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+DefaultReuseIdentifier.swift"; sourceTree = "<group>"; };
78011A681D47AF5100EA16A2 /* CellCreationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellCreationType.swift; sourceTree = "<group>"; };
78011AB21D48B53600EA16A2 /* ApiRequestParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiRequestParameters.swift; sourceTree = "<group>"; };
7824CA511CFEE6B700D7B132 /* UIImage+RenderTemplate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+RenderTemplate.swift"; sourceTree = "<group>"; };
780D23421DA412470084620D /* CGImage+Alpha.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Alpha.swift"; sourceTree = "<group>"; };
780D23451DA416F80084620D /* CGContext+Initializers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGContext+Initializers.swift"; sourceTree = "<group>"; };
7837F60E1CBCF5C0000D74C1 /* EstimatedViewHeightProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EstimatedViewHeightProtocol.swift; sourceTree = "<group>"; };
785C33441CFC908800C4C4AA /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
786A17A01CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+CapInsetsUtils.swift"; sourceTree = "<group>"; };
786D78E71D53C378006B2CEA /* AlamofireRequest+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AlamofireRequest+Extensions.swift"; sourceTree = "<group>"; };
786D78E91D53C43E006B2CEA /* ApiError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiError.swift; sourceTree = "<group>"; };
786D78EB1D53C46E006B2CEA /* AlamofireManager+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AlamofireManager+Extensions.swift"; sourceTree = "<group>"; };
787682F91CAD40C200532AB3 /* StaticEstimatedViewHeightProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticEstimatedViewHeightProtocol.swift; sourceTree = "<group>"; };
787783621CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSIndexPath+ImmutableIndexPath.swift"; sourceTree = "<group>"; };
787783621CA03CA0001CDC9B /* IndexPath+ImmutableIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "IndexPath+ImmutableIndexPath.swift"; sourceTree = "<group>"; };
787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SizeCalculation.swift"; sourceTree = "<group>"; };
787A07191D085750009EC97F /* CellsControllerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellsControllerProtocol.swift; sourceTree = "<group>"; };
788EC1591CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+InstantiateViewController.swift"; sourceTree = "<group>"; };
78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+DefaultNibName.swift"; path = "LeadKit/Extensions/UIView/UIView+DefaultNibName.swift"; sourceTree = SOURCE_ROOT; };
78B036401DA4D7060021D5CC /* UIImage+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Extensions.swift"; sourceTree = "<group>"; };
78B036421DA4FEC90021D5CC /* CGImage+Transform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Transform.swift"; sourceTree = "<group>"; };
78B036441DA561D00021D5CC /* CGImage+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Utils.swift"; sourceTree = "<group>"; };
78B036461DA5624D0021D5CC /* CGImage+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Creation.swift"; sourceTree = "<group>"; };
78B036481DA562C30021D5CC /* CGImage+Template.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Template.swift"; sourceTree = "<group>"; };
78B0364A1DA61EDE0021D5CC /* CGImage+Crop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Crop.swift"; sourceTree = "<group>"; };
78B036581DA624C10021D5CC /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = ../../../Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; };
78B036591DA624C10021D5CC /* CocoaLumberjack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaLumberjack.framework; path = ../../../Carthage/Build/iOS/CocoaLumberjack.framework; sourceTree = "<group>"; };
78B0365A1DA624C10021D5CC /* Mapper.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Mapper.framework; path = ../../../Carthage/Build/iOS/Mapper.framework; sourceTree = "<group>"; };
78B0365B1DA624C10021D5CC /* RxAlamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxAlamofire.framework; path = ../../../Carthage/Build/iOS/RxAlamofire.framework; sourceTree = "<group>"; };
78B0365C1DA624C10021D5CC /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = ../../../Carthage/Build/iOS/RxCocoa.framework; sourceTree = "<group>"; };
78B0365D1DA624C10021D5CC /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = ../../../Carthage/Build/iOS/RxSwift.framework; sourceTree = "<group>"; };
78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogFormatter.swift; sourceTree = "<group>"; };
78B0FC7E1C6B2C4D00358B64 /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
78B0FC801C6B2CD500358B64 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Transformations.swift"; sourceTree = "<group>"; };
78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Resize.swift"; sourceTree = "<group>"; };
78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Creation.swift"; sourceTree = "<group>"; };
78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+Rounding.swift"; sourceTree = "<group>"; };
78C36F801D8021DD00E7EBEA /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = "<group>"; };
78CFEE2A1C5C456B00F50370 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -116,14 +112,8 @@
78CFEE4E1C5C45E500F50370 /* StoryboardIdentifierProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardIdentifierProtocol.swift; sourceTree = "<group>"; };
78CFEE4F1C5C45E500F50370 /* ViewHeightProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewHeightProtocol.swift; sourceTree = "<group>"; };
78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewModelProtocol.swift; sourceTree = "<group>"; };
78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectsGenerator.swift; sourceTree = "<group>"; };
78E59B1A1C77470A00C6BFE9 /* ViewsGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewsGenerator.swift; sourceTree = "<group>"; };
95B39A771D9BFCC30057BD54 /* UIImageView+LoadingImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIImageView+LoadingImage.swift"; path = "UIImageView/UIImageView+LoadingImage.swift"; sourceTree = "<group>"; };
95B39A791D9BFD550057BD54 /* UIImage+Loading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Loading.swift"; sourceTree = "<group>"; };
95B39A7B1D9C05260057BD54 /* UIImage+Gradients.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Gradients.swift"; sourceTree = "<group>"; };
95B39A7D1D9C069B0057BD54 /* UIImage+Text.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Text.swift"; sourceTree = "<group>"; };
95B39A7F1D9C09440057BD54 /* UIImage+Cropping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Cropping.swift"; sourceTree = "<group>"; };
95B39A831D9C0C3E0057BD54 /* UIImage+Alpha.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Alpha.swift"; sourceTree = "<group>"; };
78D4B5451DA64D49005B0764 /* UIViewController+DefaultStoryboardIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+DefaultStoryboardIdentifier.swift"; sourceTree = "<group>"; };
78D4B5491DA64EAB005B0764 /* Any+TypeName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Any+TypeName.swift"; sourceTree = "<group>"; };
95B39A851D9D51250057BD54 /* String+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Localization.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -132,11 +122,12 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0A3BB9721D5DCFE100B03CBD /* RxSwift.framework in Frameworks */,
0A3BB96F1D5DCFE100B03CBD /* CocoaLumberjack.framework in Frameworks */,
0A3BB9701D5DCFE100B03CBD /* Mapper.framework in Frameworks */,
0A3BB9741D5DCFEC00B03CBD /* RxCocoa.framework in Frameworks */,
0A3BB9711D5DCFE100B03CBD /* RxAlamofire.framework in Frameworks */,
78B036601DA624C10021D5CC /* Mapper.framework in Frameworks */,
78B0365F1DA624C10021D5CC /* CocoaLumberjack.framework in Frameworks */,
78B036631DA624C10021D5CC /* RxSwift.framework in Frameworks */,
78B0365E1DA624C10021D5CC /* Alamofire.framework in Frameworks */,
78B036621DA624C10021D5CC /* RxCocoa.framework in Frameworks */,
78B036611DA624C10021D5CC /* RxAlamofire.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -154,11 +145,12 @@
0A3BB96A1D5DCFBD00B03CBD /* Frameworks */ = {
isa = PBXGroup;
children = (
0A3BB9731D5DCFEC00B03CBD /* RxCocoa.framework */,
0A3BB96B1D5DCFE100B03CBD /* CocoaLumberjack.framework */,
0A3BB96C1D5DCFE100B03CBD /* Mapper.framework */,
0A3BB96D1D5DCFE100B03CBD /* RxAlamofire.framework */,
0A3BB96E1D5DCFE100B03CBD /* RxSwift.framework */,
78B036581DA624C10021D5CC /* Alamofire.framework */,
78B036591DA624C10021D5CC /* CocoaLumberjack.framework */,
78B0365A1DA624C10021D5CC /* Mapper.framework */,
78B0365B1DA624C10021D5CC /* RxAlamofire.framework */,
78B0365C1DA624C10021D5CC /* RxCocoa.framework */,
78B0365D1DA624C10021D5CC /* RxSwift.framework */,
);
path = Frameworks;
sourceTree = "<group>";
@ -166,7 +158,6 @@
78011A651D47AF3000EA16A2 /* Enums */ = {
isa = PBXGroup;
children = (
78011A681D47AF5100EA16A2 /* CellCreationType.swift */,
786D78E91D53C43E006B2CEA /* ApiError.swift */,
);
path = Enums;
@ -188,13 +179,25 @@
path = Api;
sourceTree = "<group>";
};
785C33431CFC89EF00C4C4AA /* Controllers */ = {
780D23411DA412330084620D /* CGImage */ = {
isa = PBXGroup;
children = (
785C33441CFC908800C4C4AA /* TableViewController.swift */,
780D23421DA412470084620D /* CGImage+Alpha.swift */,
78B036421DA4FEC90021D5CC /* CGImage+Transform.swift */,
78B036441DA561D00021D5CC /* CGImage+Utils.swift */,
78B036461DA5624D0021D5CC /* CGImage+Creation.swift */,
78B036481DA562C30021D5CC /* CGImage+Template.swift */,
78B0364A1DA61EDE0021D5CC /* CGImage+Crop.swift */,
);
name = Controllers;
path = ../Controllers;
path = CGImage;
sourceTree = "<group>";
};
780D23441DA416E80084620D /* CGContext */ = {
isa = PBXGroup;
children = (
780D23451DA416F80084620D /* CGContext+Initializers.swift */,
);
path = CGContext;
sourceTree = "<group>";
};
786D78E61D53C355006B2CEA /* Alamofire */ = {
@ -206,12 +209,12 @@
path = Alamofire;
sourceTree = "<group>";
};
787783611CA03C84001CDC9B /* NSIndexPath */ = {
787783611CA03C84001CDC9B /* IndexPath */ = {
isa = PBXGroup;
children = (
787783621CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift */,
787783621CA03CA0001CDC9B /* IndexPath+ImmutableIndexPath.swift */,
);
path = NSIndexPath;
path = IndexPath;
sourceTree = "<group>";
};
787783651CA04D14001CDC9B /* String */ = {
@ -226,8 +229,6 @@
78A74EAA1C6B401800FE9724 /* Classes */ = {
isa = PBXGroup;
children = (
785C33431CFC89EF00C4C4AA /* Controllers */,
78E59B171C773E9600C6BFE9 /* Cache */,
78B0FC7B1C6B2BAE00358B64 /* Logging */,
);
path = Classes;
@ -286,6 +287,7 @@
78CFEE441C5C45E500F50370 /* Extensions */,
78011A651D47AF3000EA16A2 /* Enums */,
78CFEE491C5C45E500F50370 /* Protocols */,
78D4B54B1DA650FC005B0764 /* Functions */,
78CFEE2D1C5C456B00F50370 /* LeadKit.h */,
78CFEE2F1C5C456B00F50370 /* Info.plist */,
);
@ -304,15 +306,17 @@
78CFEE441C5C45E500F50370 /* Extensions */ = {
isa = PBXGroup;
children = (
95B39A761D9BFC930057BD54 /* UIImageView */,
78C36F7F1D8021D100E7EBEA /* UIColor */,
78C36F7C1D801E2F00E7EBEA /* Double */,
787783651CA04D14001CDC9B /* String */,
787783611CA03C84001CDC9B /* NSIndexPath */,
787783611CA03C84001CDC9B /* IndexPath */,
78E59B2C1C786CD500C6BFE9 /* UIView */,
78E59B2B1C786CBF00C6BFE9 /* UITableView */,
C37210711ACDF1042F70C2EB /* UIImage */,
780D23411DA412330084620D /* CGImage */,
780D23441DA416E80084620D /* CGContext */,
C372153938A7B7D327F55124 /* UIStoryboard */,
78D4B5441DA64D31005B0764 /* UIViewController */,
786D78E61D53C355006B2CEA /* Alamofire */,
);
path = Extensions;
@ -330,18 +334,24 @@
78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */,
787682F91CAD40C200532AB3 /* StaticEstimatedViewHeightProtocol.swift */,
7837F60E1CBCF5C0000D74C1 /* EstimatedViewHeightProtocol.swift */,
787A07191D085750009EC97F /* CellsControllerProtocol.swift */,
);
path = Protocols;
sourceTree = "<group>";
};
78E59B171C773E9600C6BFE9 /* Cache */ = {
78D4B5441DA64D31005B0764 /* UIViewController */ = {
isa = PBXGroup;
children = (
78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */,
78E59B1A1C77470A00C6BFE9 /* ViewsGenerator.swift */,
78D4B5451DA64D49005B0764 /* UIViewController+DefaultStoryboardIdentifier.swift */,
);
path = Cache;
path = UIViewController;
sourceTree = "<group>";
};
78D4B54B1DA650FC005B0764 /* Functions */ = {
isa = PBXGroup;
children = (
78D4B5491DA64EAB005B0764 /* Any+TypeName.swift */,
);
path = Functions;
sourceTree = "<group>";
};
78E59B2B1C786CBF00C6BFE9 /* UITableView */ = {
@ -363,27 +373,10 @@
path = UIView;
sourceTree = "<group>";
};
95B39A761D9BFC930057BD54 /* UIImageView */ = {
isa = PBXGroup;
children = (
95B39A771D9BFCC30057BD54 /* UIImageView+LoadingImage.swift */,
);
name = UIImageView;
sourceTree = "<group>";
};
C37210711ACDF1042F70C2EB /* UIImage */ = {
isa = PBXGroup;
children = (
786A17A01CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift */,
7824CA511CFEE6B700D7B132 /* UIImage+RenderTemplate.swift */,
78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */,
78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */,
78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */,
95B39A791D9BFD550057BD54 /* UIImage+Loading.swift */,
95B39A7B1D9C05260057BD54 /* UIImage+Gradients.swift */,
95B39A7D1D9C069B0057BD54 /* UIImage+Text.swift */,
95B39A7F1D9C09440057BD54 /* UIImage+Cropping.swift */,
95B39A831D9C0C3E0057BD54 /* UIImage+Alpha.swift */,
78B036401DA4D7060021D5CC /* UIImage+Extensions.swift */,
);
path = UIImage;
sourceTree = "<group>";
@ -456,14 +449,16 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Touch Instinct";
TargetAttributes = {
78CFEE291C5C456B00F50370 = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
78CFEE331C5C456B00F50370 = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
};
};
@ -558,48 +553,42 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
78011A691D47AF5100EA16A2 /* CellCreationType.swift in Sources */,
785C33451CFC908800C4C4AA /* TableViewController.swift in Sources */,
7837F60F1CBCF5C0000D74C1 /* EstimatedViewHeightProtocol.swift in Sources */,
78CFEE541C5C45E500F50370 /* UIView+LoadFromNib.swift in Sources */,
78D4B5461DA64D49005B0764 /* UIViewController+DefaultStoryboardIdentifier.swift in Sources */,
78CFEE521C5C45E500F50370 /* UITableView+CellRegistration.swift in Sources */,
78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */,
78D4B54A1DA64EAB005B0764 /* Any+TypeName.swift in Sources */,
78CFEE571C5C45E500F50370 /* StaticNibNameProtocol.swift in Sources */,
788EC15A1CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift in Sources */,
787783671CA04D4A001CDC9B /* String+SizeCalculation.swift in Sources */,
78B036431DA4FEC90021D5CC /* CGImage+Transform.swift in Sources */,
78011A641D47ABC500EA16A2 /* UIView+DefaultReuseIdentifier.swift in Sources */,
78CFEE531C5C45E500F50370 /* UITableView+DequeueCustomCell.swift in Sources */,
95B39A781D9BFCC30057BD54 /* UIImageView+LoadingImage.swift in Sources */,
786D78EC1D53C46E006B2CEA /* AlamofireManager+Extensions.swift in Sources */,
95B39A841D9C0C3E0057BD54 /* UIImage+Alpha.swift in Sources */,
95B39A801D9C09440057BD54 /* UIImage+Cropping.swift in Sources */,
78E59B1B1C77470A00C6BFE9 /* ViewsGenerator.swift in Sources */,
78B0FC811C6B2CD500358B64 /* App.swift in Sources */,
78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */,
78B036491DA562C30021D5CC /* CGImage+Template.swift in Sources */,
786D78EA1D53C43E006B2CEA /* ApiError.swift in Sources */,
787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */,
780D23461DA416F80084620D /* CGContext+Initializers.swift in Sources */,
95B39A861D9D51250057BD54 /* String+Localization.swift in Sources */,
78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */,
78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */,
78CFEE561C5C45E500F50370 /* ReuseIdentifierProtocol.swift in Sources */,
78B036411DA4D7060021D5CC /* UIImage+Extensions.swift in Sources */,
786D78E81D53C378006B2CEA /* AlamofireRequest+Extensions.swift in Sources */,
78C36F811D8021DD00E7EBEA /* UIColor+Hex.swift in Sources */,
78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */,
78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */,
78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */,
95B39A7A1D9BFD550057BD54 /* UIImage+Loading.swift in Sources */,
7824CA521CFEE6B700D7B132 /* UIImage+RenderTemplate.swift in Sources */,
780D23431DA412470084620D /* CGImage+Alpha.swift in Sources */,
78CFEE5A1C5C45E500F50370 /* ViewHeightProtocol.swift in Sources */,
787682FA1CAD40C300532AB3 /* StaticEstimatedViewHeightProtocol.swift in Sources */,
95B39A7E1D9C069B0057BD54 /* UIImage+Text.swift in Sources */,
78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */,
786A17A11CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift in Sources */,
78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */,
78CFEE581C5C45E500F50370 /* StaticViewHeightProtocol.swift in Sources */,
787783631CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift in Sources */,
787783631CA03CA0001CDC9B /* IndexPath+ImmutableIndexPath.swift in Sources */,
78B036471DA5624D0021D5CC /* CGImage+Creation.swift in Sources */,
78B0364B1DA61EDE0021D5CC /* CGImage+Crop.swift in Sources */,
78B036451DA561D00021D5CC /* CGImage+Utils.swift in Sources */,
78CFEE591C5C45E500F50370 /* StoryboardIdentifierProtocol.swift in Sources */,
78011AB31D48B53600EA16A2 /* ApiRequestParameters.swift in Sources */,
95B39A7C1D9C05260057BD54 /* UIImage+Gradients.swift in Sources */,
78B0FC7D1C6B2BE200358B64 /* LogFormatter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -636,8 +625,10 @@
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_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -660,7 +651,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -684,8 +675,10 @@
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_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -702,9 +695,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -715,6 +709,7 @@
78CFEE3F1C5C456B00F50370 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@ -727,17 +722,19 @@
);
INFOPLIST_FILE = LeadKit/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = ru.touchin.LeadKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
78CFEE401C5C456B00F50370 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@ -750,11 +747,12 @@
);
INFOPLIST_FILE = LeadKit/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = ru.touchin.LeadKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -765,6 +763,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = ru.touchin.LeadKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -775,6 +774,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = ru.touchin.LeadKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,57 +0,0 @@
//
// ObjectsPool.swift
// LeadKit
//
// Created by Иван Смолин on 19/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/// class that generates objects on initialization phase and then return its when necessary
public class ObjectsGenerator<T> {
private var objects = [T]()
private let poolSize: UInt
typealias ObjectConstructor = () -> T
private let objectsContructor: ObjectConstructor
private let serialQueue = dispatch_queue_create("ru.touchin.LeadKit.ObjectsGenerator<\(T.self)>", DISPATCH_QUEUE_SERIAL)
/**
initializer function
- parameter poolSize: number of objects to generate
- parameter contructor: objects constructor closure
*/
init(poolSize: UInt, objectsContructor contructor: ObjectConstructor) {
self.poolSize = poolSize
self.objectsContructor = contructor
fillPool()
}
private func fillPool() {
for _ in 0..<poolSize {
objects.append(objectsContructor())
}
}
/**
method which returns object from pool
- returns: object from pool
*/
public func get() -> T {
dispatch_sync(serialQueue) {
if self.objects.count < 1 {
self.fillPool()
}
}
return objects.popLast()!
}
}

View File

@ -1,23 +0,0 @@
//
// TableViewCellsPool.swift
// LeadKit
//
// Created by Иван Смолин on 19/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/// class that generates views on initialization phase and then return its when necessary
public class ViewsGenerator<T where T: UIView>: ObjectsGenerator<T> {
/**
initializer function
- parameter poolSize: number of cells to generate
- parameter nibName: view nib name
*/
init(poolSize: UInt, nibName: String) {
super.init(poolSize: poolSize, objectsContructor: { T.loadFromNib(named: nibName) })
}
}

View File

@ -8,20 +8,21 @@
import Foundation
public class App {
private static let stringVendorIdentifierKey = "stringIdentifierForVendor"
open class App {
fileprivate static let stringVendorIdentifierKey = "stringIdentifierForVendor"
/// The value of CFBundleName
public static let bundleName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
open static let bundleName = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
/// The value of CFBundleShortVersionString
public static let shortVersion = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
open static let shortVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
/// The value of CFBundleVersion
public static let bundleVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
open static let bundleVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? ""
/**
Return app's version
- returns: shortBundleVersion.bundleVersion
*/
public static func version() -> String {
open static var version: String {
return App.shortVersion + "." + App.bundleVersion
}
@ -29,14 +30,16 @@ public class App {
Return device identifier
- returns: UUIDString
*/
public static func stringIdentifierForVendor() -> String {
var returnValue = NSUserDefaults.standardUserDefaults().stringForKey(App.stringVendorIdentifierKey)
if returnValue == nil {
returnValue = NSUUID().UUIDString
NSUserDefaults.standardUserDefaults().setObject(returnValue, forKey: App.stringVendorIdentifierKey)
NSUserDefaults.standardUserDefaults().synchronize()
open static var stringIdentifierForVendor: String {
if let vendorIdentifier = UserDefaults.standard.string(forKey: App.stringVendorIdentifierKey) {
return vendorIdentifier
}
return returnValue!
let vendorIdentifier = UUID().uuidString
UserDefaults.standard.set(vendorIdentifier, forKey: App.stringVendorIdentifierKey)
UserDefaults.standard.synchronize()
return vendorIdentifier
}
}

View File

@ -9,24 +9,25 @@
import Foundation
import CocoaLumberjack
public class Log {
open class Log {
/// Logger for CocoaLumberJack
public let fileLogger = DDFileLogger()
open let fileLogger = DDFileLogger()
init() {
DDLog.add(fileLogger)
DDLog.addLogger(fileLogger)
DDLog.add(DDASLLogger.sharedInstance())
DDLog.add(DDTTYLogger.sharedInstance())
DDLog.addLogger(DDASLLogger.sharedInstance())
DDLog.addLogger(DDTTYLogger.sharedInstance())
let logFormatter = LogFormatter()
DDASLLogger.sharedInstance().logFormatter = LogFormatter()
DDTTYLogger.sharedInstance().logFormatter = LogFormatter()
DDASLLogger.sharedInstance().logFormatter = logFormatter
DDTTYLogger.sharedInstance().logFormatter = logFormatter
let assertionHandler = NSAssertionHandler()
NSThread.currentThread().threadDictionary.setValue(assertionHandler, forKey: NSAssertionHandlerKey)
Thread.current.threadDictionary.setValue(assertionHandler, forKey: NSAssertionHandlerKey)
}
/**
@ -34,10 +35,10 @@ public class Log {
- returns: Return value looks like "AppName 1.0.1 session started on version 9.2 (build 13c75)"
*/
public static func startMessage() -> String {
open static var startMessage: String {
let startMessage = App.bundleName + " " + App.shortVersion + "."
+ App.bundleVersion + " session started on "
+ NSProcessInfo.processInfo().operatingSystemVersionString.lowercaseString
+ ProcessInfo.processInfo.operatingSystemVersionString.lowercased()
return startMessage
}

View File

@ -11,33 +11,33 @@ import CocoaLumberjack
import CocoaLumberjack.DDDispatchQueueLogFormatter
class LogFormatter: DDDispatchQueueLogFormatter {
let dateFormatter: NSDateFormatter
fileprivate let dateFormatter: DateFormatter
override init() {
dateFormatter = NSDateFormatter()
dateFormatter.formatterBehavior = .Behavior10_4
dateFormatter = DateFormatter()
dateFormatter.formatterBehavior = .behavior10_4
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss:SSS"
super.init()
}
override func formatLogMessage(logMessage: DDLogMessage!) -> String {
var level: String!
override func format(message logMessage: DDLogMessage) -> String {
let level: String
switch logMessage.flag {
case DDLogFlag.Error:
case DDLogFlag.error:
level = "ERR"
case DDLogFlag.Warning:
case DDLogFlag.warning:
level = "WRN"
case DDLogFlag.Info:
case DDLogFlag.info:
level = "INF"
case DDLogFlag.Debug:
case DDLogFlag.debug:
level = "DBG"
default:
level = "VRB"
}
let dateAndTime = dateFormatter.stringFromDate(logMessage.timestamp)
let dateAndTime = dateFormatter.string(from: logMessage.timestamp)
return "\(level) \(dateAndTime) [\(logMessage.fileName):\(logMessage.line)]: \(logMessage.message)"
}

View File

@ -1,109 +0,0 @@
//
// TableViewController.swift
// LeadKit
//
// Created by Ivan Smolin on 30/05/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public class TableViewController: UITableViewController, CellsControllerProtocol {
private var cellsObjectsCreators: [String: ViewsGenerator<UITableViewCell>] = [:]
private let cellCreationType: CellCreationType
private static let creationTypeKey = "CellCreationType"
// MARK: - Initialization
public init(style: UITableViewStyle, cellCreationType: CellCreationType = .OnTheFlight) {
self.cellCreationType = cellCreationType
super.init(style: style)
}
public required init?(coder aDecoder: NSCoder) {
if let creationType = CellCreationType(rawValue: aDecoder.decodeIntegerForKey(TableViewController.creationTypeKey)) {
cellCreationType = creationType
super.init(coder: aDecoder)
} else {
return nil
}
}
public override func encodeWithCoder(aCoder: NSCoder) {
super.encodeWithCoder(aCoder)
aCoder.encodeInteger(cellCreationType.rawValue, forKey: TableViewController.creationTypeKey)
}
/**
method which adds cells generator for cells with specified reuse identifier
- parameter cellsGenerator: cells generator
- parameter cellIdentifier: cell reuse identifier
*/
public func registerCellsGenerator(cellsGenerator: ViewsGenerator<UITableViewCell>,
forCellsWithIdentifier cellIdentifier: String) {
cellsObjectsCreators[cellIdentifier] = cellsGenerator
}
// MARK: - UITableViewDataSource
public override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell
let cellIdentifier = cellIdentifierForIndexPath(indexPath)
switch cellCreationType {
case .OnTheFlight:
cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
case .Preloaded:
guard let cellsGenerator = cellsObjectsCreators[cellIdentifier] else {
fatalError("You should register view generator for cell with identifier \"\(cellIdentifier)\"")
}
cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) ?? cellsGenerator.get()
}
configureCell(cell, atIndexPath: indexPath)
return cell
}
// MARK: - Cells сontroller stub implementation
/**
method which returns reuse identifier for cell at specified index path
- parameter indexPath: NSIndexPath object
- returns: reuse identifier
*/
public func cellIdentifierForIndexPath(indexPath: NSIndexPath) -> String {
fatalError("Your should implement cellIdentifierForIndexPath(_:)")
}
/**
method which configures cell before it can be used
- parameter cell: UITableView or subclass cell
- parameter atIndexPath: index path of cell
*/
public func configureCell(cell: UITableViewCell, atIndexPath: NSIndexPath) {
// intended to be implemented in subclasses
}
/**
method which return height for cell at specified index path
- parameter indexPath: NSIndexPath object
- returns: height of cell at specified index path
*/
public func heightForCellAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
// intended to be implemented in subclasses
return UITableViewAutomaticDimension
}
}

View File

@ -13,10 +13,10 @@
- JSONSerialization: JSON serialization error
- ObjectSerialization: object mapping error
*/
public enum RequestError: ErrorType {
public enum RequestError: Error {
case Network(error: NSError)
case JSONSerialization(error: NSError)
case Mapping(reason: String)
case network(error: Error)
case jsonSerialization(error: Error)
case mapping(reason: String)
}

View File

@ -1,22 +0,0 @@
//
// CellCreationType.swift
// LeadKit
//
// Created by Ivan Smolin on 26/07/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/**
enum which describes cell creation behaviour of CellsControllerProtocol
- Preloaded: cells is generated in advance
- OnTheFlight: cells is created on demand
*/
public enum CellCreationType: Int {
case Preloaded = 0
case OnTheFlight = 1
}

View File

@ -10,7 +10,7 @@ import Alamofire
import RxSwift
import RxAlamofire
public extension Alamofire.Manager {
public extension Alamofire.SessionManager {
/**
method which executes request with given api parameters
@ -19,12 +19,12 @@ public extension Alamofire.Manager {
- returns: Observable with request
*/
func apiRequest(apiParameters: ApiRequestParameters) -> Observable<Request> {
return rx_request(apiParameters.method,
apiParameters.url,
parameters: apiParameters.parameters,
encoding: apiParameters.encoding,
headers: apiParameters.headers)
func apiRequest(requestParameters: ApiRequestParameters) -> Observable<DataRequest> {
return RxAlamofire.request(requestParameters.method,
requestParameters.url,
parameters: requestParameters.parameters,
encoding: requestParameters.encoding,
headers: requestParameters.headers)
}
}

View File

@ -10,36 +10,39 @@ import Alamofire
import RxSwift
import Mapper
import RxAlamofire
import struct RxCocoa.Reactive
public extension Alamofire.Request {
public extension Reactive where Base: DataRequest {
/**
method which serialize response into target object
- returns: Observable with HTTP URL Response and target object
*/
func apiResponse<T: Mappable>() -> Observable<(NSHTTPURLResponse, T)> {
let mapperSerializer = ResponseSerializer<T, RequestError> { request, response, data, error in
func apiResponse<T: Mappable>() -> Observable<(HTTPURLResponse, T)> {
let mapperSerializer = DataResponseSerializer<T> { request, response, data, error in
if let err = error {
return .Failure(.Network(error: err))
return .failure(RequestError.network(error: err))
}
let jsonResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let jsonResponseSerializer = DataRequest.jsonResponseSerializer()
let result = jsonResponseSerializer.serializeResponse(request, response, data, error)
switch result {
case .Success(let value):
if let responseObject = value as? NSDictionary, mappedObject = T.from(responseObject) {
return .Success(mappedObject)
case .success(let value):
if let responseObject = value as? NSDictionary, let mappedObject = T.from(responseObject) {
return .success(mappedObject)
} else {
return .Failure(.Mapping(reason: "JSON could not be mapped into response object. JSON: \(value)"))
let failureReason = "JSON could not be mapped into response object. JSON: \(value)"
return .failure(RequestError.mapping(reason: failureReason))
}
case .Failure(let error):
return .Failure(.JSONSerialization(error: error))
case .failure(let error):
return .failure(RequestError.jsonSerialization(error: error))
}
}
return rx_responseResult(responseSerializer: mapperSerializer)
return responseResult(responseSerializer: mapperSerializer)
}
}

View File

@ -0,0 +1,55 @@
//
// CGContext+Initializers.swift
// LeadKit
//
// Created by Ivan Smolin on 04/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGContext {
/**
method which creates an instance of CGContext with parameters taken from a given image
- parameter forCGImage: CGImage instance from which the parameters will be taken
- parameter fallbackColorSpace: fallback color space if image doesn't have it
*/
public static func create(forCGImage cgImage: CGImage,
fallbackColorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB()) -> CGContext? {
return create(width: cgImage.width,
height: cgImage.height,
bitmapInfo: cgImage.bitmapInfo,
colorSpace: cgImage.colorSpace ?? fallbackColorSpace,
bitsPerComponent: cgImage.bitsPerComponent)
}
/**
method which creates an instance of CGContext
- parameter width: The width, in pixels, of the required bitmap.
- parameter height: The height, in pixels, of the required bitmap.
- parameter bitmapInfo: Constants that specify whether the bitmap should contain an alpha channel,
the alpha channels relative location in a pixel,
and information about whether the pixel components are floating-point or integer values.
- parameter colorSpace: The color space to use for the bitmap context.
- parameter bitsPerComponent: The number of bits to use for each component of a pixel in memory.
*/
public static func create(width: Int,
height: Int,
bitmapInfo: CGBitmapInfo = alphaBitmapInfo,
colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB(),
bitsPerComponent: Int = 8) -> CGContext? {
return CGContext(data: nil,
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: 0,
space: colorSpace,
bitmapInfo: bitmapInfo.rawValue)
}
}

View File

@ -0,0 +1,39 @@
//
// CGImage+Alpha.swift
// LeadKit
//
// Created by Ivan Smolin on 04/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGImage {
/**
- returns: true if the image has an alpha layer.
*/
public var hasAlpha: Bool {
switch alphaInfo {
case .first, .last, .premultipliedFirst, .premultipliedLast:
return true
default:
return false
}
}
/**
- returns: a copy of the given image, adding an alpha channel if it doesn't already have one.
*/
public func applyAlpha() -> CGImage? {
guard !hasAlpha else {
return self
}
let ctx = CGContext.create(width: width, height: height, bitmapInfo: alphaBitmapInfo)
ctx?.draw(self, in: bounds)
return ctx?.makeImage()
}
}

View File

@ -0,0 +1,64 @@
//
// CGImage+Creation.swift
// LeadKit
//
// Created by Ivan Smolin on 05/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGImage {
/**
method which creates new CGImage instance filled by given color
- parameter color: color to fill
- parameter width: width of new image
- parameter height: height of new image
- parameter opaque: a flag indicating whether the bitmap is opaque (default: False)
- returns: new instanse of UIImage with given size and color
*/
public static func create(color: CGColor,
width: Int,
height: Int,
opaque: Bool = false) -> CGImage? {
let context = CGContext.create(width: width,
height: height,
bitmapInfo: opaque ? opaqueBitmapInfo : alphaBitmapInfo)
guard let ctx = context else {
return nil
}
ctx.setFillColor(color)
ctx.fill(CGRect(origin: CGPoint.zero, size: CGSize(width: width, height: height)))
return ctx.makeImage()
}
/**
creates an image from a UIView.
- parameter fromView: The source view.
- returns A new image
*/
public static func create(fromView view: UIView) -> CGImage? {
let size = view.bounds.size
let ctxWidth = Int(ceil(size.width))
let ctxHeight = Int(ceil(size.height))
guard let ctx = CGContext.create(width: ctxWidth, height: ctxHeight) else {
return nil
}
view.layer.render(in: ctx)
return ctx.makeImage()
}
}

View File

@ -0,0 +1,35 @@
//
// CGImage+Crop.swift
// LeadKit
//
// Created by Ivan Smolin on 06/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGImage {
/**
crop image to square from center
- returns: cropped image
*/
public func cropFromCenterToSquare() -> CGImage? {
let shortest = min(width, height)
let widthCropSize = width > shortest ? (width - shortest) : 0
let heightCropSize = height > shortest ? (height - shortest) : 0
let left = widthCropSize / 2
let top = heightCropSize / 2
let cropRect = CGRect(x: left,
y: top,
width: width - widthCropSize,
height: height - heightCropSize)
return cropping(to: cropRect)
}
}

View File

@ -0,0 +1,39 @@
//
// CGImage+Template.swift
// LeadKit
//
// Created by Ivan Smolin on 05/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGImage {
/**
method which render current template CGImage into new image using given color
- parameter withColor: color which used to fill template image
- returns: new CGImage rendered with given color or nil if something goes wrong
*/
public func renderTemplate(withColor color: CGColor) -> CGImage? {
guard let ctx = CGContext.create(forCGImage: self) ?? CGContext.create(width: width, height: height) else {
return nil
}
let imageRect = bounds
ctx.setFillColor(color)
ctx.translateBy(x: 0, y: CGFloat(height))
ctx.scaleBy(x: 1.0, y: -1.0)
ctx.clip(to: imageRect, mask: self)
ctx.fill(imageRect)
ctx.setBlendMode(.multiply)
return ctx.makeImage()
}
}

View File

@ -0,0 +1,189 @@
//
// CGImage+Transform.swift
// LeadKit
//
// Created by Ivan Smolin on 05/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
public extension CGImage {
/**
creates a new image with rounded corners.
- parameter withRadius: The corner radius.
- returns: A new image
*/
public func round(withRadius radius: CGFloat) -> CGImage? {
guard let ctx = CGContext.create(forCGImage: self) ?? CGContext.create(width: width, height: height) else {
return nil
}
ctx.addPath(UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath)
ctx.clip()
ctx.draw(self, in: bounds)
return ctx.makeImage()
}
/**
creates a new image with a border.
- parameter width: The size of the border.
- parameter color: The color of the border.
- parameter radius: The corner radius.
- parameter extendSize: Extend result image size and don't overlap source image by border.
- returns: A new image
*/
public func applyBorder(width border: CGFloat,
color: CGColor,
radius: CGFloat = 0,
extendSize: Bool = false) -> CGImage? {
let offset = extendSize ? border : 0
let newWidth = CGFloat(width) + offset * 2
let newHeight = CGFloat(height) + offset * 2
let ctxWidth = Int(ceil(newWidth))
let ctxHeight = Int(ceil(newHeight))
let ctxRect: CGRect = CGRect(origin: CGPoint.zero, size: CGSize(width: newWidth, height: newHeight))
let context = CGContext.create(width: ctxWidth,
height: ctxHeight,
bitmapInfo: bitmapInfo,
colorSpace: colorSpace ?? CGColorSpaceCreateDeviceRGB(),
bitsPerComponent: bitsPerComponent)
guard let ctx = context ?? CGContext.create(width: width, height: height) else {
return nil
}
ctx.draw(self, in: CGRect(x: offset, y: offset, width: CGFloat(width), height: CGFloat(height)))
ctx.setStrokeColor(color)
let widthDiff = CGFloat(ctxWidth) - newWidth // difference between context width and real width
let heightDiff = CGFloat(ctxWidth) - newWidth // difference between context height and real height
let inset = ctxRect.insetBy(dx: border / 2 + widthDiff, dy: border / 2 + heightDiff)
if radius != 0 {
ctx.setLineWidth(border)
ctx.addPath(UIBezierPath(roundedRect: inset, cornerRadius: radius).cgPath)
ctx.strokePath()
} else {
ctx.stroke(inset, width: border)
}
return ctx.makeImage()
}
/**
creates a resized copy of an image.
- parameter newSize: the new size of the image.
- parameter contentMode: the way to handle the content in the new size.
- returns: a new image
*/
public func resize(newSize: CGSize, contentMode: ImageContentMode = .scaleToFill) -> CGImage? {
let ctxWidth = Int(ceil(newSize.width))
let ctxHeight = Int(ceil(newSize.height))
let context = CGContext.create(width: ctxWidth,
height: ctxHeight,
bitmapInfo: bitmapInfo,
colorSpace: colorSpace ?? CGColorSpaceCreateDeviceRGB(),
bitsPerComponent: bitsPerComponent)
guard let ctx = context ?? CGContext.create(width: ctxWidth, height: ctxHeight) else {
return nil
}
let horizontalRatio = newSize.width / CGFloat(width)
let verticalRatio = newSize.height / CGFloat(height)
let ratio: CGFloat
switch contentMode {
case .scaleToFill:
ratio = 1
case .scaleAspectFill:
ratio = max(horizontalRatio, verticalRatio)
case .scaleAspectFit:
ratio = min(horizontalRatio, verticalRatio)
}
let newImageWidth = contentMode == .scaleToFill ? newSize.width : CGFloat(width) * ratio
let newImageHeight = contentMode == .scaleToFill ? newSize.height : CGFloat(height) * ratio
let originX: CGFloat
let originY: CGFloat
if newImageWidth > newSize.width {
originX = (newSize.width - newImageWidth) / 2
} else if newImageWidth < newSize.width {
originX = newSize.width / 2 - newImageWidth / 2
} else {
originX = 0
}
if newImageHeight > newSize.height {
originY = (newSize.height - newImageHeight) / 2
} else if newImageHeight < newSize.height {
originY = newSize.height / 2 - newImageHeight / 2
} else {
originY = 0
}
let rect = CGRect(origin: CGPoint(x: originX, y: originY),
size: CGSize(width: newImageWidth, height: newImageHeight))
ctx.interpolationQuality = .high
ctx.draw(self, in: rect)
return ctx.makeImage()
}
/**
returns a copy of the image with border of the given size added around its edges.
- parameter padding: The padding amount.
- returns: A new image.
*/
public func applyPadding(_ padding: CGFloat) -> CGImage? {
let ctxWidth = Int(ceil(CGFloat(width) + padding * 2))
let ctxHeight = Int(ceil(CGFloat(height) + padding * 2))
let context = CGContext.create(width: ctxWidth,
height: ctxHeight,
bitmapInfo: bitmapInfo,
colorSpace: colorSpace ?? CGColorSpaceCreateDeviceRGB(),
bitsPerComponent: bitsPerComponent)
guard let ctx = context ?? CGContext.create(width: ctxWidth, height: ctxHeight) else {
return nil
}
// Draw the image in the center of the context, leaving a gap around the edges
let imageLocation = CGRect(x: padding,
y: padding,
width: CGFloat(width),
height: CGFloat(height))
ctx.addRect(imageLocation)
ctx.clip()
ctx.draw(self, in: imageLocation)
return ctx.makeImage()
}
}

View File

@ -0,0 +1,29 @@
//
// CGImage+Utils.swift
// LeadKit
//
// Created by Ivan Smolin on 05/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import CoreGraphics
// The bitmapInfo value are hard-coded to prevent an "unsupported parameter combination" error
public let alphaBitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo().rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
public let opaqueBitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo().rawValue | CGImageAlphaInfo.none.rawValue)
public enum ImageContentMode {
case scaleToFill, scaleAspectFit, scaleAspectFill
}
public extension CGImage {
/**
- returns: bounds of image.
*/
var bounds: CGRect {
return CGRect(origin: CGPoint.zero, size: CGSize(width: width, height: height))
}
}

View File

@ -17,8 +17,8 @@ public extension Double {
- Down: From 167.567 you will get 167.5
*/
public enum RoundingType {
case Normal
case Down
case normal
case down
}
/**
@ -30,14 +30,14 @@ public extension Double {
- returns: rounded value
*/
public func roundValue(withPersicion persicion: UInt,
roundType: RoundingType = .Normal) -> Double {
roundType: RoundingType = .normal) -> Double {
let divider = pow(10.0, Double(persicion))
switch roundType {
case .Normal:
return round(self * divider) / divider
case .Down:
return Double(Int(self * divider)) / divider
case .normal:
return (self * divider).rounded(.up) / divider
case .down:
return (self * divider).rounded(.down) / divider
}
}

View File

@ -1,5 +1,5 @@
//
// NSIndexPath+ImmutableIndexPath.swift
// IndexPath+ImmutableIndexPath.swift
// LeadKit
//
// Created by Иван Смолин on 21/03/16.
@ -10,14 +10,14 @@ import Foundation
// http://stackoverflow.com/a/21686163
extension NSIndexPath {
extension IndexPath {
/// return immutable copy if class is not NSIndexPath or return self
var immutableIndexPath: NSIndexPath {
if Mirror(reflecting: self).subjectType == NSIndexPath.self { // check for UIMutableIndexPath
var immutableIndexPath: IndexPath {
if Mirror(reflecting: self).subjectType == IndexPath.self { // check for UIMutableIndexPath
return self
}
return NSIndexPath(forItem: item, inSection: section)
return IndexPath(item: item, section: section)
}
}

View File

@ -6,7 +6,7 @@
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
import Foundation
public extension String {

View File

@ -52,11 +52,11 @@ public extension String {
- returns: string size calculation result
*/
public func size(withAttributes attributes: [String: AnyObject]?,
maxWidth: CGFloat = CGFloat.max,
maxHeight: CGFloat = CGFloat.max) -> StringSizeCalculationResult {
maxWidth: CGFloat = CGFloat.greatestFiniteMagnitude,
maxHeight: CGFloat = CGFloat.greatestFiniteMagnitude) -> StringSizeCalculationResult {
let size = self.boundingRectWithSize(CGSize(width: maxWidth, height: maxHeight),
options: [.UsesLineFragmentOrigin, .UsesFontLeading],
let size = self.boundingRect(with: CGSize(width: maxWidth, height: maxHeight),
options: [.usesLineFragmentOrigin, .usesFontLeading],
attributes: attributes,
context: nil).size

View File

@ -75,7 +75,13 @@ public extension UIColor {
- parameter alpha: alpha component used if not given in hexString
*/
public convenience init?(hexString: String, alpha: CGFloat = 1) {
let hexStr = hexString.hasPrefix("#") ? hexString.substringFromIndex(hexString.startIndex.advancedBy(1)) : hexString
let hexStr: String
if hexString.hasPrefix("#") {
hexStr = hexString.substring(from: hexString.characters.index(hexString.startIndex, offsetBy: 1))
} else {
hexStr = hexString
}
let charactersCount = hexStr.characters.count

View File

@ -1,123 +0,0 @@
//
// UIImage+Alpha.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
- returns: true if the image has an alpha layer.
*/
public func hasAlpha() -> Bool {
let alpha = CGImageGetAlphaInfo(CGImage)
switch alpha {
case .First, .Last, .PremultipliedFirst, .PremultipliedLast:
return true
default:
return false
}
}
/**
- returns: a copy of the given image, adding an alpha channel if it doesn't already have one.
*/
public func applyAlpha() -> UIImage? {
guard !hasAlpha() else {
return self
}
let imageRef = CGImage
let width = CGImageGetWidth(imageRef)
let height = CGImageGetHeight(imageRef)
let colorSpace = CGImageGetColorSpace(imageRef)
// The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrderDefault.rawValue |
CGImageAlphaInfo.PremultipliedFirst.rawValue)
let offscreenContext = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpace, bitmapInfo.rawValue)
// Draw the image into the context and retrieve the new image, which will now have an alpha layer
CGContextDrawImage(offscreenContext,
CGRect(x: 0, y: 0, width: width, height: height),
imageRef)
guard let cgImage = CGBitmapContextCreateImage(offscreenContext) else {
return nil
}
let imageWithAlpha = UIImage(CGImage: cgImage)
return imageWithAlpha
}
/**
returns a copy of the image with a transparent border of the given size added around its edges.
i.e. For rotating an image without getting jagged edges.
- parameter padding: The padding amount.
- returns: A new image.
*/
public func applyPadding(padding: CGFloat) -> UIImage? {
// If the image does not have an alpha layer, add one
guard let image = applyAlpha() else {
return nil
}
let rect = CGRect(x: 0, y: 0, width: size.width + padding * 2, height: size.height + padding * 2)
// Build a context that's the same dimensions as the new size
let colorSpace = CGImageGetColorSpace(CGImage)
let bitmapInfo = CGImageGetBitmapInfo(CGImage)
let bitsPerComponent = CGImageGetBitsPerComponent(CGImage)
let context = CGBitmapContextCreate(nil,
Int(rect.size.width),
Int(rect.size.height),
bitsPerComponent, 0, colorSpace,
bitmapInfo.rawValue)
// Draw the image in the center of the context, leaving a gap around the edges
let imageLocation = CGRect(x: padding, y: padding, width: image.size.width, height: image.size.height)
CGContextDrawImage(context, imageLocation, CGImage)
// Create a mask to make the border transparent, and combine it with the image
let imageWithPadding = imageRefWithPadding(padding, size: rect.size)
guard let cgImage = CGImageCreateWithMask(CGBitmapContextCreateImage(context), imageWithPadding) else {
return nil
}
let transparentImage = UIImage(CGImage: cgImage)
return transparentImage
}
/**
creates a mask that makes the outer edges transparent and everything else opaque.
The size must include the entire mask (opaque part + transparent border).
- parameter padding: The padding amount.
- parameter size: The size of the image.
- returns: A Core Graphics Image Ref
*/
private func imageRefWithPadding(padding: CGFloat,
size: CGSize) -> CGImageRef? {
// Build a context that's the same dimensions as the new size
let colorSpace = CGColorSpaceCreateDeviceGray()
let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrderDefault.rawValue | CGImageAlphaInfo.None.rawValue)
let context = CGBitmapContextCreate(nil, Int(size.width), Int(size.height), 8, 0, colorSpace, bitmapInfo.rawValue)
// Start with a mask that's entirely transparent
CGContextSetFillColorWithColor(context, UIColor.blackColor().CGColor)
CGContextFillRect(context, CGRect(x: 0, y: 0, width: size.width, height: size.height))
// Make the inner part (within the border) opaque
CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
let fillRect = CGRect(x: padding,
y: padding,
width: size.width - padding * 2,
height: size.height - padding * 2)
CGContextFillRect(context, fillRect)
// Get an image of the context
let maskImageRef = CGBitmapContextCreateImage(context)
return maskImageRef
}
}

View File

@ -1,71 +0,0 @@
//
// UIImage+CapInsetsUtils.swift
// LeadKit
//
// Created by Иван Смолин on 09/04/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
this method tries to find requested image with specific parameters in cache, and if doesn't exists - create it
- parameter name: name of the image used in UIImage(named:)
- parameter size: size of rendered image
- parameter capInsets: cap insets for image
- parameter cache: cache to search
- returns: cached or newly created image or nil if no such image find with specified name
*/
public static func fetchOrCreateImageWithName(name: String,
size: CGSize,
capInsets: UIEdgeInsets,
cache: NSCache) -> UIImage? {
let cacheKey = "\(name)-\(NSStringFromUIEdgeInsets(capInsets))-\(NSStringFromCGSize(size))"
if let cachedImage = cache.objectForKey(cacheKey) as? UIImage {
return cachedImage
}
if let renderedImage = UIImage(named: name)?.resizableImageWithCapInsets(capInsets).renderWithSize(size) {
cache.setObject(renderedImage, forKey: cacheKey)
return renderedImage
}
return nil
}
/**
this method tries to find requested image with specific parameters in cache, and if doesn't exists - create it
- parameter name: name of the image used in UIImage(named:)
- parameter size: size of rendered image
- parameter assetsInsetsForScales: mapping of screen scale to UIEdgeInsets which defined in XCAssets
- parameter cache: cache to search
- returns: cached or newly created image or nil if no such image find with specified name
*/
public static func fetchOrCreateImageWithName(name: String,
size: CGSize,
assetsInsetsForScales: [CGFloat: UIEdgeInsets],
cache: NSCache) -> UIImage? {
let scale = UIScreen.mainScreen().scale
if let assetsInsetsForScale = assetsInsetsForScales[scale] {
let capInsetsForScale = UIEdgeInsets(top: assetsInsetsForScale.top / scale,
left: assetsInsetsForScale.left / scale,
bottom: assetsInsetsForScale.bottom / scale,
right: assetsInsetsForScale.right / scale)
return fetchOrCreateImageWithName(name, size: size, capInsets: capInsetsForScale, cache: cache)
}
return nil
}
}

View File

@ -1,57 +0,0 @@
//
// UIImage+Creation.swift
// LeadKit
//
// Created by Ivan Smolin on 07/09/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
method which creates new UIImage instance filled by given color
- parameter color: color to fill
- parameter size: size of new image
- parameter opaque: a flag indicating whether the bitmap is opaque (default: False)
- parameter scale: screen scale (default: 0 (pick a device scale))
- returns: new instanse of UIImage with given size and color
*/
public static func imageWith(color: UIColor, size: CGSize, opaque: Bool = false, scale: CGFloat = 0) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
defer { UIGraphicsEndImageContext() }
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, CGRect(origin: CGPoint.zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
/**
creates an image from a UIView.
- parameter fromView: The source view.
- returns A new image
*/
public convenience init?(fromView view: UIView) {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
view.layer.renderInContext(context)
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else {
return nil
}
self.init(CGImage: cgImage)
UIGraphicsEndImageContext()
}
}

View File

@ -1,44 +0,0 @@
//
// UIImage+Cropping.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
creates a cropped copy of an image.
- parameter bounds: The bounds of the rectangle inside the image.
- returns: A new image
*/
public func crop(bounds: CGRect) -> UIImage? {
guard let cgImage = CGImageCreateWithImageInRect(CGImage, bounds) else {
return nil
}
return UIImage(CGImage: cgImage,
scale: 0.0,
orientation: imageOrientation)
}
/**
crop image to square
- returns: cropped image
*/
public func cropToSquare() -> UIImage? {
let scaledSize = CGSize(width: size.width * scale, height: size.height * scale)
let shortest = min(scaledSize.width, scaledSize.height)
let left: CGFloat = scaledSize.width > shortest ? (scaledSize.width-shortest)/2 : 0
let top: CGFloat = scaledSize.height > shortest ? (scaledSize.height-shortest)/2 : 0
let rect = CGRect(x: 0, y: 0, width: scaledSize.width, height: scaledSize.height)
let insetRect = CGRectInset(rect, left, top)
return crop(insetRect)
}
}

View File

@ -0,0 +1,155 @@
//
// UIImage+Extensions.swift
// LeadKit
//
// Created by Ivan Smolin on 05/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
method which creates new UIImage instance filled by given color
- parameter color: color to fill
- parameter size: size of new image
- returns: new instanse of UIImage with given size and color
*/
public convenience init?(color: UIColor, size: CGSize) {
let cgImage = CGImage.create(color: color.cgColor,
width: Int(ceil(size.width)),
height: Int(ceil(size.height)))
guard let image = cgImage else {
return nil
}
self.init(cgImage: image)
}
/**
creates an image from a UIView.
- parameter fromView: The source view.
- returns A new image or nil if something goes wrong.
*/
public convenience init?(fromView view: UIView) {
guard let cgImage = CGImage.create(fromView: view) else {
return nil
}
self.init(cgImage: cgImage)
}
/**
method which render current template CGImage into new image using given color
- parameter withColor: color which used to fill template image
- returns: new CGImage rendered with given color or nil if something goes wrong
*/
public func renderTemplate(withColor color: UIColor) -> UIImage? {
return cgImage?.renderTemplate(withColor: color.cgColor)?.uiImage
}
/**
creates a new image with rounded corners and border.
- parameter cornerRadius: The corner radius.
- parameter border: The size of the border.
- parameter color: The color of the border.
- parameter extendSize: Extend result image size and don't overlap source image by border.
- returns: A new image
*/
public func roundCorners(cornerRadius: CGFloat,
borderWidth: CGFloat,
color: UIColor,
extendSize: Bool = false) -> UIImage? {
let rounded = cgImage?.round(withRadius: cornerRadius)
return rounded?.applyBorder(width: borderWidth,
color: color.cgColor,
radius: cornerRadius,
extendSize: extendSize)?.uiImage
}
/**
creates a new circle image.
- returns: A new image
*/
public func roundCornersToCircle() -> UIImage? {
return cgImage?.round(withRadius: CGFloat(min(size.width, size.height) / 2))?.uiImage
}
/**
creates a new circle image with a border.
- parameter border: CGFloat The size of the border.
- parameter color: UIColor The color of the border.
- parameter extendSize: Extend result image size and don't overlap source image by border.
- returns: UIImage?
*/
public func roundCornersToCircle(borderWidth: CGFloat,
borderColor: UIColor,
extendSize: Bool = false) -> UIImage? {
let radius = CGFloat(min(size.width, size.height) / 2)
let rounded = cgImage?.round(withRadius: radius)
return rounded?.applyBorder(width: borderWidth,
color: borderColor.cgColor,
radius: radius,
extendSize: extendSize)?.uiImage
}
/**
creates a resized copy of an image.
- parameter newSize: the new size of the image.
- parameter contentMode: the way to handle the content in the new size.
- returns: a new image
*/
public func resize(newSize: CGSize, contentMode: ImageContentMode = .scaleToFill) -> UIImage? {
return cgImage?.resize(newSize: newSize, contentMode: contentMode)?.uiImage
}
/**
creates a cropped copy of an image.
- parameter to: The bounds of the rectangle inside the image.
- returns: A new image
*/
public func crop(to bounds: CGRect) -> UIImage? {
return cgImage?.cropping(to: bounds)?.uiImage
}
/**
crop image to square from center
- returns: cropped image
*/
public func cropFromCenterToSquare() -> UIImage? {
return cgImage?.cropFromCenterToSquare()?.uiImage
}
}
public extension CGImage {
public var uiImage: UIImage {
return UIImage(cgImage: self)
}
}

View File

@ -1,123 +0,0 @@
//
// UIImage+Gradients.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
creates a gradient color image.
- parameter gradientColors: An array of colors to use for the gradient.
- parameter size: Image size (defaults: 10x10)
*/
public convenience init?(gradientColors: [UIColor],
size: CGSize = CGSize(width: 10, height: 10)) {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colors = gradientColors.map { $0.CGColor }
let gradient = CGGradientCreateWithColors(colorSpace, colors, nil)
CGContextDrawLinearGradient(context,
gradient,
CGPoint(x: 0, y: 0),
CGPoint(x: 0, y: size.height),
CGGradientDrawingOptions(rawValue: 0))
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else {
return nil
}
self.init(CGImage: cgImage)
UIGraphicsEndImageContext()
}
/**
applies gradient color overlay to an image.
- parameter gradientColors: An array of colors to use for the gradient.
- parameter blendMode: The blending type to use.
- returns: A new image
*/
public func applyGradientColors(gradientColors: [UIColor],
blendMode: CGBlendMode = .Normal) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0, size.height)
CGContextScaleCTM(context, 1.0, -1.0)
CGContextSetBlendMode(context, blendMode)
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
CGContextDrawImage(context, rect, CGImage)
// Create gradient
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colors = gradientColors.map { $0.CGColor }
let gradient = CGGradientCreateWithColors(colorSpace, colors, nil)
// Apply gradient
CGContextClipToMask(context, rect, CGImage)
CGContextDrawLinearGradient(context,
gradient,
CGPoint(x: 0, y: 0),
CGPoint(x: 0, y: size.height),
CGGradientDrawingOptions(rawValue: 0))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
/**
creates a radial gradient.
- parameter startColor: The start color
- parameter endColor: The end color
- parameter radialGradientCenter: The gradient center (default:0.5,0.5).
- parameter radius: Radius size (default: 0.5)
- parameter size: Image size (default: 100x100)
*/
public convenience init?(startColor: UIColor,
endColor: UIColor,
radialGradientCenter: CGPoint = CGPoint(x: 0.5, y: 0.5),
radius: CGFloat = 0.5,
size: CGSize = CGSize(width: 100, height: 100)) {
UIGraphicsBeginImageContextWithOptions(size, true, 0)
let numLocations: Int = 2
let locations: [CGFloat] = [0.0, 1.0]
let startComponents = CGColorGetComponents(startColor.CGColor)
let endComponents = CGColorGetComponents(endColor.CGColor)
let components: [CGFloat] = [startComponents[0],
startComponents[1],
startComponents[2],
startComponents[3],
endComponents[0],
endComponents[1],
endComponents[2],
endComponents[3]] as [CGFloat]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, numLocations)
// Normalize the 0-1 ranged inputs to the width of the image
let aCenter = CGPoint(x: radialGradientCenter.x * size.width,
y: radialGradientCenter.y * size.height)
let aRadius = (min(size.width, size.height)) * (radius)
// Draw it
CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(),
gradient, aCenter, 0,
aCenter, aRadius,
CGGradientDrawingOptions.DrawsAfterEndLocation)
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else {
return nil
}
self.init(CGImage: cgImage)
// Clean up
UIGraphicsEndImageContext()
}
}

View File

@ -1,72 +0,0 @@
//
// UIImage+Loading.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
import QuartzCore
import CoreGraphics
import Accelerate
public enum UIImageContentMode {
case ScaleToFill, ScaleAspectFit, ScaleAspectFill
}
public extension UIImage {
/**
a singleton shared NSURL cache used for images from URL
*/
private static let sharedCache = NSCache()
// MARK: Image From URL
/**
creates a new image from a URL with optional caching.
if using cache, the cached image is returned.
otherwise, a place holder is used until the image from web is returned by the fetchComplete.
- parameter url: The image URL.
- parameter placeholder: The placeholder image.
- parameter cacheImage: Weather or not we should cache the NSURL response (default: true)
- parameter fetchComplete: Returns the image from the web the first time is fetched.
- returns: A new image
*/
public class func imageFromURL(url: String,
placeholder: UIImage,
cacheImage: Bool = true,
fetchComplete: (image: UIImage?) -> ()) -> UIImage? {
// From Cache
if cacheImage {
if let image = UIImage.sharedCache.objectForKey(url) as? UIImage {
fetchComplete(image: nil)
return image
}
}
// Fetch Image
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
if let nsURL = NSURL(string: url) {
session.dataTaskWithURL(nsURL, completionHandler: { (data, response, error) -> Void in
if error != nil {
dispatch_async(dispatch_get_main_queue()) {
fetchComplete(image: nil)
}
} else if let data = data, image = UIImage(data: data) {
if cacheImage {
UIImage.sharedCache.setObject(image, forKey: url)
}
dispatch_async(dispatch_get_main_queue()) {
fetchComplete(image: image)
}
}
session.finishTasksAndInvalidate()
}).resume()
}
return placeholder
}
}

View File

@ -1,46 +0,0 @@
//
// UIImage+RenderTemplate.swift
// LeadKit
//
// Created by Ivan Smolin on 01/06/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
method which render current template UIImage into new image using given color
- parameter color: color which used to fill template image
- parameter opaque: a flag indicating whether the bitmap is opaque (default: False)
- returns: new UIImage rendered with given color
*/
public func renderTemplateWithColor(color: UIColor, opaque: Bool = false) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
defer { UIGraphicsEndImageContext() }
let ctx = UIGraphicsGetCurrentContext()
let imageRect = CGRect(origin: CGPoint.zero, size: size)
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
CGContextSetRGBFillColor(ctx, r, g, b, a)
CGContextTranslateCTM(ctx, 0, size.height)
CGContextScaleCTM(ctx, 1.0, -1.0)
CGContextClipToMask(ctx, imageRect, CGImage)
CGContextFillRect(ctx, imageRect)
CGContextSetBlendMode(ctx, .Multiply)
CGContextDrawImage(ctx, imageRect, CGImage)
return UIGraphicsGetImageFromCurrentImageContext()
}
}

View File

@ -1,79 +0,0 @@
//
// UIImage+Resize.swift
// LeadKit
//
// Created by Ivan Smolin on 07/09/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
method which render current UIImage for specific size and return new UIImage
- parameter size: size of new image
- parameter opaque: a flag indicating whether the bitmap is opaque (default: False)
- returns: new instance of UIImage rendered with given size
*/
public func renderWithSize(size: CGSize, opaque: Bool = false) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
defer { UIGraphicsEndImageContext() }
drawInRect(CGRect(origin: CGPoint.zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
/**
creates a resized copy of an image.
- parameter size: the new size of the image.
- parameter contentMode: the way to handle the content in the new size.
- returns: a new image
*/
public func resize(size: CGSize,
contentMode: UIImageContentMode = .ScaleToFill) -> UIImage? {
let horizontalRatio = size.width / size.width
let verticalRatio = size.height / size.height
var ratio: CGFloat = 1
switch contentMode {
case .ScaleToFill:
ratio = 1
case .ScaleAspectFill:
ratio = max(horizontalRatio, verticalRatio)
case .ScaleAspectFit:
ratio = min(horizontalRatio, verticalRatio)
}
let rect = CGRect(x: 0, y: 0, width: size.width * ratio, height: size.height * ratio)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
let context = CGBitmapContextCreate(nil,
Int(rect.size.width),
Int(rect.size.height), 8, 0, colorSpace,
bitmapInfo.rawValue)
let transform = CGAffineTransformIdentity
CGContextConcatCTM(context, transform)
// Set the quality level to use when rescaling
guard let interpolationQuality = CGInterpolationQuality(rawValue: 3) else {
return nil
}
CGContextSetInterpolationQuality(context, interpolationQuality)
CGContextDrawImage(context, rect, CGImage)
guard let newContext = context, cgImage = CGBitmapContextCreateImage(newContext) else {
return nil
}
return UIImage(CGImage: cgImage,
scale: scale,
orientation: imageOrientation)
}
}

View File

@ -1,45 +0,0 @@
//
// UIImage+Text.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
creates a text label image.
- parameter text: The text to use in the label.
- parameter font: The font (default: System font of size 18)
- parameter color: The text color (default: White)
- parameter backgroundColor: The background color (default:Gray).
- parameter size: Image size (default: 10x10)
- parameter offset: Center offset (default: 0x0)
*/
public convenience init?(text: String,
font: UIFont = UIFont.systemFontOfSize(18),
color: UIColor = UIColor.whiteColor(),
backgroundColor: UIColor = UIColor.grayColor(),
size: CGSize = CGSize(width: 10, height: 10),
offset: CGPoint = CGPoint(x: 0, y: 0)) {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
label.font = font
label.text = text
label.textColor = color
label.textAlignment = .Center
label.backgroundColor = backgroundColor
let image = UIImage(fromView: label)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
image?.drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height))
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else {
return nil
}
self.init(CGImage: cgImage)
UIGraphicsEndImageContext()
}
}

View File

@ -1,154 +0,0 @@
//
// UIImage+Transformations.swift
// LeadKit
//
// Created by Ivan Smolin on 07/09/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
public extension UIImage {
/**
method which creates new UIImage from current with rounded corners
- parameter radius: corners radius
- parameter opaque: a flag indicating whether the bitmap is opaque (default: False)
- returns: new UIImage instance rendered with given radius
*/
public func roundedImage(withRadius radius: CGFloat, opaque: Bool = false) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
defer { UIGraphicsEndImageContext() }
let imageRect = CGRect(origin: CGPoint.zero, size: size)
UIBezierPath(roundedRect: imageRect, cornerRadius: radius).addClip()
drawInRect(imageRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
/**
creates a new image with rounded corners.
- parameter cornerRadius: The corner radius.
- returns: A new image
*/
public func roundCorners(cornerRadius: CGFloat) -> UIImage? {
guard let imageWithAlpha = applyAlpha() else {
return nil
}
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let width = CGImageGetWidth(imageWithAlpha.CGImage)
let height = CGImageGetHeight(imageWithAlpha.CGImage)
let bits = CGImageGetBitsPerComponent(imageWithAlpha.CGImage)
let colorSpace = CGImageGetColorSpace(imageWithAlpha.CGImage)
let bitmapInfo = CGImageGetBitmapInfo(imageWithAlpha.CGImage)
let context = CGBitmapContextCreate(nil, width, height, bits, 0, colorSpace, bitmapInfo.rawValue)
let rect = CGRect(x: 0, y: 0, width: CGFloat(width) * scale, height: CGFloat(height) * scale)
CGContextBeginPath(context)
if cornerRadius == 0 {
CGContextAddRect(context, rect)
} else {
CGContextSaveGState(context)
CGContextTranslateCTM(context, rect.minX, rect.minY)
CGContextScaleCTM(context, cornerRadius, cornerRadius)
let roundedWidth = rect.size.width / cornerRadius
let roundedHeight = rect.size.height / cornerRadius
CGContextMoveToPoint(context, roundedWidth, roundedHeight/2)
CGContextAddArcToPoint(context, roundedWidth, roundedHeight, roundedWidth/2, roundedHeight, 1)
CGContextAddArcToPoint(context, 0, roundedHeight, 0, roundedHeight/2, 1)
CGContextAddArcToPoint(context, 0, 0, roundedWidth/2, 0, 1)
CGContextAddArcToPoint(context, roundedWidth, 0, roundedWidth, roundedHeight/2, 1)
CGContextRestoreGState(context)
}
CGContextClosePath(context)
CGContextClip(context)
CGContextDrawImage(context, rect, imageWithAlpha.CGImage)
guard let bitmapImage = CGBitmapContextCreateImage(context) else {
return nil
}
let image = UIImage(CGImage: bitmapImage,
scale: scale,
orientation: .Up)
UIGraphicsEndImageContext()
return image
}
/**
creates a new image with rounded corners and border.
- parameter cornerRadius: The corner radius.
- parameter border: The size of the border.
- parameter color: The color of the border.
- returns: A new image
*/
public func roundCorners(cornerRadius: CGFloat,
border: CGFloat,
color: UIColor) -> UIImage? {
return roundCorners(cornerRadius)?.applyBorder(border, color: color)
}
/**
creates a new circle image.
- returns: A new image
*/
public func roundCornersToCircle() -> UIImage? {
let shortest = min(size.width, size.height)
return cropToSquare()?.roundCorners(shortest/2)
}
/**
creates a new circle image with a border.
- parameter border: CGFloat The size of the border.
- parameter color: UIColor The color of the border.
- returns: UIImage?
*/
public func roundCornersToCircle(border border: CGFloat, color: UIColor) -> UIImage? {
let shortest = min(size.width, size.height)
return cropToSquare()?.roundCorners(shortest/2, border: border, color: color)
}
/**
creates a new image with a border.
- parameter border: The size of the border.
- parameter color: The color of the border.
- returns: A new image
*/
public func applyBorder(border: CGFloat,
color: UIColor) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let width = CGImageGetWidth(CGImage)
let height = CGImageGetHeight(CGImage)
let bits = CGImageGetBitsPerComponent(CGImage)
let colorSpace = CGImageGetColorSpace(CGImage)
let bitmapInfo = CGImageGetBitmapInfo(CGImage)
let context = CGBitmapContextCreate(nil, width, height, bits, 0, colorSpace, bitmapInfo.rawValue)
var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
CGContextSetRGBStrokeColor(context, red, green, blue, alpha)
CGContextSetLineWidth(context, border)
let rect = CGRect(x: 0, y: 0, width: size.width*scale, height: size.height*scale)
let inset = CGRectInset(rect, border*scale, border*scale)
CGContextStrokeEllipseInRect(context, inset)
CGContextDrawImage(context, inset, CGImage)
guard let bitmapImage = CGBitmapContextCreateImage(context) else {
return nil
}
let image = UIImage(CGImage: bitmapImage)
UIGraphicsEndImageContext()
return image
}
}

View File

@ -1,52 +0,0 @@
//
// UIImageView+LoadingImage.swift
// LeadKit
//
// Created by Николай Ашанин on 28.09.16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
import QuartzCore
public extension UIImageView {
/**
loads an image from a URL. If cached, the cached image is returned.
otherwise, a place holder is used until the image from web is returned by the closure.
- parameter url: The image URL.
- parameter placeholder: The placeholder image.
- parameter fadeIn: Weather the mage should fade in.
- parameter shouldCacheImage: Should be image cached.
- parameter closure: Returns the image from the web the first time is fetched.
- returns: A new image
*/
public func imageFromURL(url: String,
placeholder: UIImage,
fadeIn: Bool = true,
shouldCacheImage: Bool = true,
closure: ((image: UIImage?) -> ())? = nil) {
image = UIImage.imageFromURL(url,
placeholder: placeholder,
cacheImage: shouldCacheImage) { [weak self]
(uploadedImage: UIImage?) in
guard let image = uploadedImage else {
return
}
self?.image = image
if fadeIn {
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
self?.layer.addAnimation(transition, forKey: nil)
}
closure?(image: image)
}
}
}

View File

@ -10,14 +10,14 @@ import UIKit
extension UIStoryboard {
/**
method for instanciating new UIViewController subclass from storyboard using storyboard identifier
method for instantiating new UIViewController subclass from storyboard using storyboard identifier
provided by StoryboardIdentifierProtocol protocol implementation
- returns: UIViewController subclass instance
*/
public func instantiateViewController<T where T: UIViewController, T: StoryboardIdentifierProtocol>() -> T {
return instantiateViewControllerWithIdentifier(T.storyboardIdentifier()) as! T
public func instantiateViewController<T>() -> T where T: UIViewController, T: StoryboardIdentifierProtocol {
return self.instantiateViewController(withIdentifier: T.storyboardIdentifier) as! T
}
}

View File

@ -8,7 +8,7 @@
import UIKit
extension UITableView {
public extension UITableView {
/**
method which register UITableViewCell subclass for reusing in UITableView with reuse identifier
provided by ReuseIdentifierProtocol protocol implementation and nib name
@ -19,9 +19,10 @@ extension UITableView {
- see: ReuseIdentifierProtocol, StaticNibNameProtocol
*/
public func registerNib<T where T: ReuseIdentifierProtocol, T: UITableViewCell, T: StaticNibNameProtocol>
(forCellClass cellClass: T.Type) {
self.registerNib(UINib(nibName: T.nibName()), forCellReuseIdentifier: T.reuseIdentifier())
public func registerNib<T>(forCellClass cellClass: T.Type)
where T: ReuseIdentifierProtocol, T: UITableViewCell, T: StaticNibNameProtocol {
self.register(UINib(nibName: T.nibName), forCellReuseIdentifier: T.reuseIdentifier)
}
/**
@ -35,10 +36,12 @@ extension UITableView {
- see: ReuseIdentifierProtocol, NibNameProtocol
*/
public func registerNib<T where T: ReuseIdentifierProtocol, T: UITableViewCell, T: NibNameProtocol>
(forCellClass cellClass: T.Type, forUserInterfaceIdiom interfaceIdiom: UIUserInterfaceIdiom) {
public func registerNib<T>(forCellClass cellClass: T.Type,
forUserInterfaceIdiom interfaceIdiom: UIUserInterfaceIdiom)
where T: ReuseIdentifierProtocol, T: UITableViewCell, T: NibNameProtocol {
let nib = UINib(nibName: T.nibName(forConfiguration: interfaceIdiom))
self.registerNib(nib, forCellReuseIdentifier: T.reuseIdentifier())
self.register(nib, forCellReuseIdentifier: T.reuseIdentifier)
}
}

View File

@ -20,9 +20,10 @@ extension UITableView {
- see: ReuseIdentifierProtocol
*/
public func dequeueReusableCell<T where T: UITableViewCell, T: ReuseIdentifierProtocol>
(forIndexPath indexPath: NSIndexPath) -> T {
return dequeueReusableCellWithIdentifier(T.reuseIdentifier(), forIndexPath: indexPath) as! T
public func dequeueReusableCell<T>(forIndexPath indexPath: IndexPath) -> T
where T: UITableViewCell, T: ReuseIdentifierProtocol {
return self.dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as! T
}
}

View File

@ -9,14 +9,14 @@
import UIKit
extension UIView: StaticNibNameProtocol {
/**
default implementation of StaticNibNameProtocol
- returns: class name string without dot (last class path component)
- returns: class name string
*/
public class func nibName() -> String {
return String(self.dynamicType).componentsSeparatedByString(".").last!
open class var nibName: String {
return className(of: self)
}
}

View File

@ -15,8 +15,8 @@ extension UIView: ReuseIdentifierProtocol {
- returns: type name string
*/
public class func reuseIdentifier() -> String {
return String(self.dynamicType)
open class var reuseIdentifier: String {
return className(of: self)
}
}

View File

@ -8,13 +8,13 @@
import UIKit
extension UINib {
public extension UINib {
convenience public init(nibName name: String) {
self.init(nibName: name, bundle: nil)
}
}
extension UIView {
public extension UIView {
/**
method which return UIView subclass instance loaded from nib using nib name provided by NibNameProtocol implementation
@ -23,8 +23,8 @@ extension UIView {
- returns: UIView subclass instance
*/
public static func loadFromNib<T where T: NibNameProtocol, T: UIView>
(forUserInterfaceIdiom interfaceIdiom: UIUserInterfaceIdiom) -> T {
public static func loadFromNib<T>
(forUserInterfaceIdiom interfaceIdiom: UIUserInterfaceIdiom) -> T where T: NibNameProtocol, T: UIView {
return loadFromNib(named: T.nibName(forConfiguration: interfaceIdiom))
}
@ -34,8 +34,8 @@ extension UIView {
- returns: UIView subclass instance
*/
public static func loadFromNib<T where T: StaticNibNameProtocol, T: UIView>() -> T {
return loadFromNib(named: T.nibName())
public static func loadFromNib<T>() -> T where T: StaticNibNameProtocol, T: UIView {
return loadFromNib(named: T.nibName)
}
/**
@ -46,7 +46,7 @@ extension UIView {
- returns: UIView subclass instance
*/
public static func loadFromNib<T>(named nibName: String) -> T {
return UINib(nibName: nibName).instantiateWithOwner(nil, options: nil).first as! T
return UINib(nibName: nibName).instantiate(withOwner: nil, options: nil).first as! T
}
}

View File

@ -0,0 +1,22 @@
//
// UIViewController+DefaultStoryboardIdentifier.swift
// LeadKit
//
// Created by Ivan Smolin on 06/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
extension UIViewController: StoryboardIdentifierProtocol {
/**
default implementation of StoryboardIdentifierProtocol
- returns: type name string
*/
open class var storyboardIdentifier: String {
return className(of: self)
}
}

View File

@ -0,0 +1,19 @@
//
// Any+TypeName.swift
// LeadKit
//
// Created by Ivan Smolin on 06/10/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
public func className<T>(of type: T) -> String {
let clsName = String(describing: type(of: type))
if let typeRange = clsName.range(of: ".Type") {
return clsName.substring(to: typeRange.lowerBound)
} else {
return clsName
}
}

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.0.3</string>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -1,36 +0,0 @@
//
// CellsControllerProtocol.swift
// LeadKit
//
// Created by Ivan Smolin on 08/06/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/**
* protocol which ensures that specific type can configure cell and return cell attributes for specific index path
*/
public protocol CellsControllerProtocol {
associatedtype CellType
/**
method which returns cell identifier for given index path
- parameter indexPath: NSIndexPath object
- returns: cell identifier for specified index path
*/
func cellIdentifierForIndexPath(indexPath: NSIndexPath) -> String
/**
method which configures given cell for given index path
- parameter cell: cell to configure
- parameter atIndexPath: index path of given cell
- returns: nothing
*/
func configureCell(cell: CellType, atIndexPath: NSIndexPath)
}

View File

@ -6,7 +6,7 @@
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
import Foundation
/**
* protocol which ensures that specific type can return nib name of view for specific configuration

View File

@ -15,11 +15,9 @@ public protocol AbstractReuseIdentifierProtocol {
associatedtype IdentifierType
/**
method which returns reuse identifier with protocol associated type
- returns: reuse identifier
- returns: reuse identifier with protocol associated type
*/
static func reuseIdentifier() -> IdentifierType
static var reuseIdentifier: IdentifierType { get }
}
/**
@ -27,9 +25,7 @@ public protocol AbstractReuseIdentifierProtocol {
*/
public protocol ReuseIdentifierProtocol: AbstractReuseIdentifierProtocol {
/**
method which returns reuse identifier with string type
- returns: reuse identifier
- returns: reuse identifier with string type
*/
static func reuseIdentifier() -> String
static var reuseIdentifier: String { get }
}

View File

@ -13,9 +13,7 @@ import Foundation
*/
public protocol StaticNibNameProtocol {
/**
static method which returns nib name
- returns: nib name string
*/
static func nibName() -> String
static var nibName: String { get }
}

View File

@ -17,5 +17,5 @@ public protocol StoryboardIdentifierProtocol {
- returns: storyboard identifier string
*/
static func storyboardIdentifier() -> String
static var storyboardIdentifier: String { get }
}

View File

@ -21,5 +21,5 @@ public protocol AbstractViewModelProtocol {
- returns: nothing
*/
func setViewModel(viewModel: ViewModelType)
func setViewModel(_ viewModel: ViewModelType)
}

View File

@ -15,17 +15,17 @@ import RxSwift
*/
public struct ApiRequestParameters {
let method: Alamofire.Method
let url: URLStringConvertible
let parameters: [String: AnyObject]?
let method: HTTPMethod
let url: URLConvertible
let parameters: Parameters?
let encoding: ParameterEncoding
let headers: [String: String]?
let headers: HTTPHeaders?
public init(method: Alamofire.Method,
url: URLStringConvertible,
parameters: [String: AnyObject]? = nil,
encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil) {
public init(url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil) {
self.method = method
self.url = url

View File

@ -7,7 +7,6 @@
//
import XCTest
@testable import LeadKit
class LeadKitTests: XCTestCase {
@ -28,7 +27,7 @@ class LeadKitTests: XCTestCase {
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
self.measure {
// Put the code you want to measure the time of here.
}
}