profile
viewpoint
SwifterSwift SwifterSwift World https://swifterswift.com We Make Swift, well, Swifter 😎

fork XheyDeveloper/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in 19 minutes

startedSwifterSwift/SwifterSwift

started time in 6 hours

startedSwifterSwift/SwifterSwift

started time in 6 hours

startedSwifterSwift/SwifterSwift

started time in 6 hours

startedSwifterSwift/SwifterSwift

started time in 11 hours

issue commentSwifterSwift/SwifterSwift

UIImage.filled(withColor:) improvement

It looks like my PR got merged this morning, so I'm closing this issue 🎉

LucianoPAlmeida

comment created time in 13 hours

issue closedSwifterSwift/SwifterSwift

UIImage.filled(withColor:) improvement

Hacktoberfest

Here we can do a minor tweak where this extension is implemented using an old UIGraphicsBeginImageContextWithOptions API. That is not recommended. We can provide an improvement for it and make this using UIGraphicsImageRenderer API.

Note: UIGraphicsImageRenderer is only available from iOS 10. So we should maintain the current implementation for lower iOS versions like:

if #available(iOS 10.0, tvOS 10.0, *) {
        // UIGraphicsImageRenderer new implementation
} else {
       // Current implementation with UIGraphicsBeginImageContextWithOptions
}

See #721 for an example.

closed time in 13 hours

LucianoPAlmeida

Pull request review commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

 public extension Array where Element: Equatable {         }     } +    /// SwifterSwift: Remove all duplicate elements removed using KeyPath to compare.+    ///+    /// - Parameter path: Key path to compare, the value must be Equatable.+    /// - Returns: an array of unique elements.+    @discardableResult+    mutating func removeDuplicates<E: Equatable>(keyPath path: KeyPath<Element, E>) -> [Element] {+        var items = [Element]()+        removeAll { (element) -> Bool in+            if !items.contains{ $0[keyPath: path] == element[keyPath: path] } {

+1

iglushchuk

comment created time in 13 hours

Pull request review commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

 public extension Array where Element: Equatable {         }     } +    /// SwifterSwift: Remove all duplicate elements removed using KeyPath to compare.+    ///+    /// - Parameter path: Key path to compare, the value must be Equatable.+    /// - Returns: an array of unique elements.+    @discardableResult+    mutating func removeDuplicates<E: Equatable>(keyPath path: KeyPath<Element, E>) -> [Element] {+        var items = [Element]()+        removeAll { (element) -> Bool in
        removeAll { element -> Bool in
iglushchuk

comment created time in 14 hours

Pull request review commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

 public extension Array where Element: Equatable {         }     } +    /// SwifterSwift: Remove all duplicate elements removed using KeyPath to compare.+    ///+    /// - Parameter path: Key path to compare, the value must be Equatable.+    /// - Returns: an array of unique elements.+    @discardableResult+    mutating func removeDuplicates<E: Equatable>(keyPath path: KeyPath<Element, E>) -> [Element] {+        var items = [Element]()+        removeAll { (element) -> Bool in+            if !items.contains{ $0[keyPath: path] == element[keyPath: path] } {

I think with early returns we usually do guard, no?

guard items.contains { $0[keyPath: path] == element[keyPath: path] } else { return true }
iglushchuk

comment created time in 14 hours

Pull request review commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

 public extension Array where Element: Equatable {         }     } +    /// SwifterSwift: Remove all duplicate elements removed using KeyPath to compare.+    ///+    /// - Parameter path: Key path to compare, the value must be Equatable.+    /// - Returns: an array of unique elements.+    @discardableResult+    mutating func removeDuplicates<E: Equatable>(keyPath path: KeyPath<Element, E>) -> [Element] {+        var items = [Element]()+        removeAll { (element) -> Bool in+            if !items.contains{ $0[keyPath: path] == element[keyPath: path] } {
            if !items.contains { $0[keyPath: path] == element[keyPath: path] } {
iglushchuk

comment created time in 14 hours

Pull request review commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

 public extension Array where Element: Equatable {         }     } +    /// SwifterSwift: Remove all duplicate elements removed using KeyPath to compare.+    ///+    /// - Parameter path: Key path to compare, the value must be Hashable.+    /// - Returns: an array of unique elements.+    @discardableResult+    mutating func removeDuplicates<E: Hashable>(keyPath path: KeyPath<Element, E>) -> [Element] {+        var set = Set<E>()+        removeAll {
        removeAll { !set.insert($0[keyPath: path]).inserted }

Just quick suggestion :))

iglushchuk

comment created time in 14 hours

pull request commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

Codecov Report

Merging #737 into master will decrease coverage by 0.49%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #737     +/-   ##
=========================================
- Coverage   92.55%   92.05%   -0.5%     
=========================================
  Files          90       90             
  Lines        3236     3260     +24     
=========================================
+ Hits         2995     3001      +6     
- Misses        241      259     +18
Flag Coverage Δ
#ios 95.26% <100%> (-0.54%) :arrow_down:
#osx 81.94% <100%> (+0.11%) :arrow_up:
#tvos 95.29% <100%> (-0.56%) :arrow_down:
Impacted Files Coverage Δ
...ces/SwifterSwift/SwiftStdlib/ArrayExtensions.swift 100% <100%> (ø) :arrow_up:
Sources/SwifterSwift/UIKit/UIImageExtensions.swift 83.43% <0%> (-10.65%) :arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 24d9edc...c96f100. Read the comment docs.

iglushchuk

comment created time in 14 hours

pull request commentSwifterSwift/SwifterSwift

Array mutable remove duplicates

<!-- 0 Errors 0 Warnings 4 Messages: Thank you for submitting a pul... 1 Markdown --> <table> <thead> <tr> <th width="50"></th> <th width="100%" data-danger-table="true" data-kind="Message"> 4 Messages </th> </tr> </thead> <tbody> <tr> <td>:book:</td> <td data-sticky="false">Thank you for submitting a pull request to SwifterSwift. The team will review your submission as soon as possible.</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">iOS: Executed 602 tests, with 0 failures (0 unexpected) in 12.777 (15.266) seconds</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">tvOS: Executed 576 tests, with 0 failures (0 unexpected) in 3.318 (5.636) seconds</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">macOS: Executed 433 tests, with 0 failures (0 unexpected) in 1.085 (1.477) seconds</td> </tr> </tbody> </table>

SwiftLint found issues

Warnings

File Line Reason
ArrayExtensions.swift 109 Opening braces should be preceded by a single space and on the same line as the declaration. (opening_brace)

<p align="right" data-meta="generated_by_danger"> Generated by :no_entry_sign: <a href="https://danger.systems/">Danger</a> </p>

iglushchuk

comment created time in 14 hours

pull request commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

Thank you for contributing to SwifterSwift! I've invited you to join the SwifterSwift GitHub organization - no pressure to accept! If you'd like more information on what that means, check out our contributing guidelines. Feel free to reach out if you have any questions! 😃

raysarebest

comment created time in 15 hours

push eventSwifterSwift/SwifterSwift

Michael Hulet

commit sha c6a93cbeb3dedca555647d59647f3847d864a696

🚀 UIGraphicsImageRenderer in filled(withColor:) (#733) * Converted filled(withColor:) to use UIGraphicsImageRenderer when available * Dropped watchOS support for UIImage.filled(withColor:) and added CHANGELOG entry * Patched filled(withColor:) to work on all platforms with the latest APIs when available * Remove unnecessary parameter parentheses Co-Authored-By: Guy Kogus <guy.kogus@gmail.com> * Reverted Xcode project to initial state, better organized changelog

view details

push time in 15 hours

PR merged SwifterSwift/SwifterSwift

Reviewers
🚀 UIGraphicsImageRenderer in filled(withColor:)

🚀 This provides a fix for Issue #732. In iOS/tvOS 10, Apple introduced the UIGraphicsImageRenderer API, which effectively replaces the older UIGraphicsImageContext method this method was using before

<!--- Provide a general summary of your changes in the Title above -->

Checklist

<!--- Please go over all the following points, and put an x in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

  • [x] I checked the Contributing Guidelines before creating this request.
  • [ ] New extensions are written in Swift 5.0.
  • [ ] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+, or use @available if not.
  • [ ] I have added tests for new extensions, and they passed.
  • [x] All extensions have a clear comments explaining their functionality, all parameters and return type in English.
  • [x] All extensions are declared as public.
  • [x] I have added a changelog entry describing my changes.

I didn't add any new extensions in this PR. I changed the internals of one to use a newer API, but everything looks exactly the same to a consumer of the method, and all the pre-existing tests pass. Do I need to check any of the other boxes?

+15 -0

4 comments

2 changed files

raysarebest

pr closed time in 15 hours

PR opened SwifterSwift/SwifterSwift

Array mutable remove duplicates

<!--- Provide a general summary of your changes in the Title above --> In this PR I have implemented and tested methods for issue #710

Checklist

<!--- Please go over all the following points, and put an x in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

  • [x] I checked the Contributing Guidelines before creating this request.
  • [x] New extensions are written in Swift 5.0.
  • [x] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+, or use @available if not.
  • [x] I have added tests for new extensions, and they passed.
  • [x] All extensions have a clear comments explaining their functionality, all parameters and return type in English.
  • [x] All extensions are declared as public.
  • [x] I have added a changelog entry describing my changes.
+46 -0

0 comment

3 changed files

pr created time in 15 hours

issue commentSwifterSwift/SwifterSwift

Mutating versions of removeDuplicates(keyPath:)

I can handle it :)

RomanPodymov

comment created time in 18 hours

fork iglushchuk/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in 18 hours

push eventSwifterSwift/SwifterSwift

Moritz Sternemann

commit sha 24d9edc485ae253a2a0b1eafcb745d1575fd831b

Add sum(for keyPath:) to Sequence (#736)

view details

push time in 20 hours

pull request commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

Thank you for contributing to SwifterSwift! I've invited you to join the SwifterSwift GitHub organization - no pressure to accept! If you'd like more information on what that means, check out our contributing guidelines. Feel free to reach out if you have any questions! 😃

moritzsternemann

comment created time in 20 hours

PR merged SwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

🚀 Sum up a Numeric property, referenced by KeyPath, of all elements in a sequence. Originally from https://swiftbysundell.com/articles/reducers-in-swift/.

Resolves #735

Checklist

<!--- Please go over all the following points, and put an x in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

  • [x] I checked the Contributing Guidelines before creating this request.
  • [x] New extensions are written in Swift 5.0.
  • [x] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+, or use @available if not.
  • [x] I have added tests for new extensions, and they passed.
  • [x] All extensions have a clear comments explaining their functionality, all parameters and return type in English.
  • [x] All extensions are declared as public.
  • [x] I have added a changelog entry describing my changes.
+18 -0

3 comments

3 changed files

moritzsternemann

pr closed time in 20 hours

issue closedSwifterSwift/SwifterSwift

Extend Sequence to get sum by keypath

Extend The Sequence type with a sum(for keyPath:) function to return the sum of nested number for all objects within a sequence

Examples from Swift by Sundell's article on reducers

let unreadCount = mailboxes.sum(for: \.unreadMessages.count)
let totalScore = levels.sum(for: \.playerScore)
let meetingDuration = today.meetings.sum(for: \.duration)

closed time in 20 hours

omaralbeik

Pull request review commentSwifterSwift/SwifterSwift

Improve UIImage.tint(color:blendMode:) using UIGraphicsImageRenderer

 public extension UIImage {         return newImage     } +    #if !os(watchOS)     /// SwifterSwift: UIImage tinted with color     ///     /// - Parameters:     ///   - color: color to tint image with.     ///   - blendMode: how to blend the tint     /// - Returns: UIImage tinted with given color.     func tint(_ color: UIColor, blendMode: CGBlendMode) -> UIImage {-        let drawRect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)-        UIGraphicsBeginImageContextWithOptions(size, false, scale)-        defer {-            UIGraphicsEndImageContext()+        let drawRect = CGRect(origin: .zero, size: size)+        if #available(iOS 10.0, tvOS 10.0, *) {+            let format = UIGraphicsImageRendererFormat()+            format.scale = scale+            let renderer = UIGraphicsImageRenderer(+                size: size,+                format: format+            )

It makes sense to me 👍

FraDeliro

comment created time in 21 hours

Pull request review commentSwifterSwift/SwifterSwift

Improve UIImage.tint(color:blendMode:) using UIGraphicsImageRenderer

 public extension UIImage {         return newImage     } +    #if !os(watchOS)     /// SwifterSwift: UIImage tinted with color     ///     /// - Parameters:     ///   - color: color to tint image with.     ///   - blendMode: how to blend the tint     /// - Returns: UIImage tinted with given color.     func tint(_ color: UIColor, blendMode: CGBlendMode) -> UIImage {

It makes sense to me, thanks for the suggestion ;) I will update it.

FraDeliro

comment created time in 21 hours

pull request commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

I've addressed the changes @guykogus requested, but it seems like the tvOS build failed, despite all targets compiling and tests passing on my machine. It looks like it's because its call to xcodebuild to compile the target exited with code 132, and from googling around a bit, it seems like that's a SourceKit crash that happens sometimes, and not actually anything wrong with the code/project. Is there any way to force a rerun of Travis?

raysarebest

comment created time in a day

startedSwifterSwift/SwifterSwift

started time in a day

startedSwifterSwift/SwifterSwift

started time in a day

fork cj-work/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in a day

Pull request review commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

 		07C50D491F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */; }; 		07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */; }; 		07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */; };-		07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */; };

Will do, but I feel like this should be PRed separately. There were a bunch of tests wrapped in #if os(iOS) added to the tvOS target. They'd never run because there isn't anything to compile for that platform, but because they exist and didn't pass anything, it'd make Xcode think the tests for tvOS weren't entirely successful

raysarebest

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@SD10 , Thanks for the invitation. Can you please brief me more about what it means.

@JayMehta97 That's an automatic message, where for every contributor when it gets its first PR merged, they are added to the organization. This basically means that you now is a member o SwifterSwift/contributors group, and you have some rights on the repo e.g. you can create branches on origin, instead of your fork... but most important is you are now part of the organization \o/

JayMehta97

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@SD10 , Thanks for the invitation. Can you please brief me more about what it means.

@LucianoPAlmeida , Thanks for merging my PR. It is my first contribution to any open source repo. Looking forward to contribute more to this.

JayMehta97

comment created time in 2 days

issue commentSwifterSwift/SwifterSwift

Use XcodeGen

@Saik0s Go for it ;)

omaralbeik

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

Danger is warning about a lot of linting issues. Make sure tot always run swiftlint autocorrect before commit.

mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `AdditiveArithmetic` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `AdditiveArithmetic` property.+    /// - Returns: The sum of the `AdditiveArithmetic` propertys at `keyPath`.+    func sum<T: AdditiveArithmetic>(for keyPath: KeyPath<Element, T>) -> T {+        // Inspired by: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(.zero) { $0 + $1[keyPath: keyPath] }

In this case not much, is more useful when we are reducing sequeces, collections where avoid the copy is a performance boost. But here, copy or not doesn't really make a difference... anyway, just a suggestion

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `AdditiveArithmetic` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `AdditiveArithmetic` property.+    /// - Returns: The sum of the `AdditiveArithmetic` propertys at `keyPath`.+    func sum<T: AdditiveArithmetic>(for keyPath: KeyPath<Element, T>) -> T {+        // Inspired by: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(.zero) { $0 + $1[keyPath: keyPath] }

Same-same, no? What benefit is there to using the mutating version?

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added "numberOfDaysLeftInYear" to "Date" extension

 public extension Date {         return timeIntervalSince1970     } +    /// SwifterSwift: Current day in a year+    var dayInYear: Int {+        return calendar.ordinality(of: .day, in: .year, for: self)!+    }++    /// SwifterSwift: How many days in a year+    var numberOfDaysInYear: Int {+        return (calendar.range(of: .day, in: .year, for: self)!.upperBound) - 1+    }++    /// SwifterSwift: How many days are left in a year+    var numberOfDaysLeftInYear: Int {

@chulbert That makes sense :)

Hero93

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

Thank you for contributing to SwifterSwift! I've invited you to join the SwifterSwift GitHub organization - no pressure to accept! If you'd like more information on what that means, check out our contributing guidelines. Feel free to reach out if you have any questions! 😃

JayMehta97

comment created time in 2 days

push eventSwifterSwift/SwifterSwift

Jay Mehta

commit sha 838615805c0409c741717a9f68c60089e2d886c4

Added 'applyGradient' method to UIViewExtensions (#726) * Added applyGradient method to UIViewExtensions * Added applyGradient method to UIViewExtensions.swift * Added testApplyGradient to UIViewExtensionsTests.swift * Updated CHANGELOG.md * Removed applyGradient(:) from UIViewExtensions and made it in CAGradientLayerExtension. * Update CHANGELOG.md Co-Authored-By: Guy Kogus <guy.kogus@gmail.com> * Update CHANGELOG.md Co-Authored-By: Guy Kogus <guy.kogus@gmail.com> * Update Sources/SwifterSwift/CoreAnimation/CAGradientLayerExtensions.swift Co-Authored-By: Guy Kogus <guy.kogus@gmail.com> * Update Sources/SwifterSwift/CoreAnimation/CAGradientLayerExtensions.swift Co-Authored-By: Guy Kogus <guy.kogus@gmail.com> * Added tests to check all of the values * Added !os(Linux) check as the build was failing for Linux. * Added non-nil values to locations for test.

view details

push time in 2 days

PR merged SwifterSwift/SwifterSwift

Reviewers
Added 'applyGradient' method to UIViewExtensions

<!--- Provide a general summary of your changes in the Title above --> 🚀

Checklist

<!--- Please go over all the following points, and put an x in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

  • [x] I checked the Contributing Guidelines before creating this request.
  • [x] New extensions are written in Swift 5.0.
  • [x] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+, or use @available if not.
  • [x] I have added tests for new extensions, and they passed.
  • [x] All extensions have a clear comments explaining their functionality, all parameters and return type in English.
  • [x] All extensions are declared as public.
  • [x] I have added a changelog entry describing my changes.
+108 -0

14 comments

6 changed files

JayMehta97

pr closed time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `AdditiveArithmetic` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `AdditiveArithmetic` property.+    /// - Returns: The sum of the `AdditiveArithmetic` propertys at `keyPath`.+    func sum<T: AdditiveArithmetic>(for keyPath: KeyPath<Element, T>) -> T {+        // Inspired by: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(.zero) { $0 + $1[keyPath: keyPath] }
        return reduce(into: .zero) { $0 += $1[keyPath: keyPath] }

Just a suggestion, what do you think?

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

Yeah, I realised straight away that "flexible" was the wrong word, but you get me ;)

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

If the intention is each function stand on its own then I agree. Perhaps the guidelines could make that a little clearer (function vs extension).

That said, I might argue anyone copying implementations out of your library isn't using your library so it's not really "more flexible." ;)

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {

Okay, got it. All the other generic functions in the Sequence extension use the type constraint syntax, so I'd like to keep it for this one as well 😇

moritzsternemann

comment created time in 2 days

fork Saik0s/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in 2 days

issue commentSwifterSwift/SwifterSwift

Use XcodeGen

Hi @omaralbeik, I would like to work on this improvement.

omaralbeik

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {

They're actually the exact same, I just prefer always using where (up to you, personally). You can do it whichever way you like 😄

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)
        let edgePadding = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let emptyItemInMapView: Void = mapView.zoom(to: emptyItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(emptyItemInMapView)+    }+    +    func testWithOneItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let oneItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243)]+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)
        let edgePadding = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let emptyItemInMapView: Void = mapView.zoom(to: emptyItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(emptyItemInMapView)+    }+    +    func testWithOneItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let oneItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243)]
        let oneItemArray = [CLLocationCoordinate2D(latitude: 36.9751, longitude: 38.4243)]
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []
        let emptyItemArray = [CLLocationCoordinate2D]()
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let emptyItemInMapView: Void = mapView.zoom(to: emptyItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(emptyItemInMapView)+    }+    +    func testWithOneItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let oneItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243)]+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let oneItemInMapView: Void = mapView.zoom(to: oneItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(oneItemInMapView)+    }+    +    func testWithMultiItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let multiItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243),+                                                        .init(latitude: 37.06622, longitude: 37.38332),+                                                        .init(latitude: 41.00527, longitude: 28.97696)]
        let multiItemArray = [CLLocationCoordinate2D(latitude: 36.9751, longitude: 38.4243),
                                            CLLocationCoordinate2D(latitude: 37.06622, longitude: 37.38332),
                                            CLLocationCoordinate2D(latitude: 41.00527, longitude: 28.97696)]
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let emptyItemInMapView: Void = mapView.zoom(to: emptyItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(emptyItemInMapView)+    }+    +    func testWithOneItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let oneItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243)]+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let oneItemInMapView: Void = mapView.zoom(to: oneItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(oneItemInMapView)+    }+    +    func testWithMultiItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)
        let edgePadding = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
mustafagunes

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added "numberOfDaysLeftInYear" to "Date" extension

 public extension Date {         return timeIntervalSince1970     } +    /// SwifterSwift: Current day in a year+    var dayInYear: Int {+        return calendar.ordinality(of: .day, in: .year, for: self)!+    }++    /// SwifterSwift: How many days in a year+    var numberOfDaysInYear: Int {+        return (calendar.range(of: .day, in: .year, for: self)!.upperBound) - 1+    }++    /// SwifterSwift: How many days are left in a year+    var numberOfDaysLeftInYear: Int {

This is picky but by Apple's naming conventions this should probably be daysRemaining(in:)

Hero93

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {

I think a type constraint is enough here, no need for a generic where clause. What do you think?

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

 		07C50D491F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */; }; 		07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */; }; 		07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */; };-		07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */; };

Please revert all of these changes.

raysarebest

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

 public extension UIImage {     /// - Parameter color: color to fill image with.     /// - Returns: UIImage filled with given color.     func filled(withColor color: UIColor) -> UIImage {++        #if !os(watchOS)+        if #available(iOS 10, tvOS 10, *) {+            let format = UIGraphicsImageRendererFormat()+            format.scale = scale+            let renderer = UIGraphicsImageRenderer(size: size, format: format)+            return renderer.image { (context) in
            return renderer.image { context in
raysarebest

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

 The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S   - Added `enumerateMatches(in:options:range:using:)`, `matches(in:options:range:)`, `numberOfMatches(in:options:range:)`, `firstMatch(in:options:range:)`, `rangeOfFirstMatch(in:options:range:)`, `stringByReplacingMatches(in:options:range:withTemplate:)`, `replaceMatches(in:options:range:withTemplate:)`, which use `String` and `String.Range` in place of `NSString` and `NSRange` to make the calls Swifter. [#727](https://github.com/SwifterSwift/SwifterSwift/pull/727) by [guykogus](https://github.com/guykogus). - **UIImage**:   - Added `withBackgroundColor(_:)` to specify a background color for a partially transparent image. [#721](https://github.com/SwifterSwift/SwifterSwift/pull/721) by [MaxHaertwig](https://github.com/maxhaertwig).+  - Implemented `filled(withColor:)` using `UIGraphicsImageRenderer` when available. [#733](https://github.com/SwifterSwift/SwifterSwift/pull/733)

This should be in the Changed section, not Added.

raysarebest

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

Thanks for your feedback @guykogus, will update the PR in a minute!

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

I found the following rule in the contributing guidelines:

  • Do not use an existing SwifterSwift extension inside another SwifterSwift extension. All extensions should be able to be copied and pasted and work immediately without having to copy another extension.

Let me know if I should change the implementation to your proposed solution regardless :)

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

SwifterSwift is designed to be copyable piecemeal, so we can't reference our own functions between themselves. Otherwise, anybody wanting to copy a function manually may find themselves traversing one function after the next. It's a big drawback, but it makes the library more flexible.

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

I'm generally a proponent of building on top of existing solutions. SwifterSwift already implements sum() so I would utilize that:

return map { $0[keyPath: keyPath] }.sum()

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {+        // Implementation from: https://swiftbysundell.com/articles/reducers-in-swift/+        return reduce(0) { sum, element in

You can 1-line this :)

        return reduce(.zero) { $0 + $1[keyPath: keyPath] }

Also notice using .zero, which is part of the protocol, as opposed to 0, which is an Int.

moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S   - Added `enumerateMatches(in:options:range:using:)`, `matches(in:options:range:)`, `numberOfMatches(in:options:range:)`, `firstMatch(in:options:range:)`, `rangeOfFirstMatch(in:options:range:)`, `stringByReplacingMatches(in:options:range:withTemplate:)`, `replaceMatches(in:options:range:withTemplate:)`, which use `String` and `String.Range` in place of `NSString` and `NSRange` to make the calls Swifter. [#727](https://github.com/SwifterSwift/SwifterSwift/pull/727) by [guykogus](https://github.com/guykogus). - **UIImage**:   - Added `withBackgroundColor(_:)` to specify a background color for a partially transparent image. [#721](https://github.com/SwifterSwift/SwifterSwift/pull/721) by [MaxHaertwig](https://github.com/maxhaertwig).+- **Sequence**:+  - Added `sum(for:)` to sum up a Numeric property, referenced by KeyPath, of all elements in a sequence. [#736](https://github.com/SwifterSwift/SwifterSwift/pull/736) by [Moritz Sternemann](https://github.com/moritzsternemann).
  - Added `sum(for:)` to sum up an `AdditiveArithmetic` property, referenced by `KeyPath`, of all elements in a sequence. [#736](https://github.com/SwifterSwift/SwifterSwift/pull/736) by [Moritz Sternemann](https://github.com/moritzsternemann).
moritzsternemann

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

 public extension Sequence {     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {         return sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }     }++    /// SwifterSwift: Sum of a `Numeric` property of each `Element` in a `Sequence`.+    ///+    ///     ["James", "Wade", "Bryant"].sum(for: \.count) -> 15+    ///+    /// - Parameter keyPath: Key path of the `Numeric` property.+    /// - Returns: The sum of the `Numeric` propertys at `keyPath`.+    func sum<T: Numeric>(for keyPath: KeyPath<Element, T>) -> T {

If you're already going for a generic implementation, why not go up a step to AdditiveArithmetic?

    func sum<T>(for keyPath: KeyPath<Element, T>) -> T where T: AdditiveArithmetic {
moritzsternemann

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

Codecov Report

Merging #736 into master will increase coverage by 0.11%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #736      +/-   ##
==========================================
+ Coverage   92.42%   92.53%   +0.11%     
==========================================
  Files          80       89       +9     
  Lines        3130     3230     +100     
==========================================
+ Hits         2893     2989      +96     
- Misses        237      241       +4
Flag Coverage Δ
#ios 95.8% <100%> (?)
#osx 81.83% <100%> (+0.03%) :arrow_up:
#tvos 95.85% <100%> (ø) :arrow_up:
Impacted Files Coverage Δ
.../SwifterSwift/SwiftStdlib/SequenceExtensions.swift 95.12% <100%> (+0.25%) :arrow_up:
...terSwift/UIKit/UIGestureRecognizerExtensions.swift 100% <0%> (ø)
...wifterSwift/UIKit/UIRefreshControlExtensions.swift 100% <0%> (ø)
...ces/SwifterSwift/UIKit/UIStackViewExtensions.swift 100% <0%> (ø)
...ources/SwifterSwift/UIKit/UISwitchExtensions.swift 100% <0%> (ø)
...es/SwifterSwift/UIKit/UIDatePickerExtensions.swift 100% <0%> (ø)
...ources/SwifterSwift/UIKit/UIWindowExtensions.swift 100% <0%> (ø)
...ces/SwifterSwift/UIKit/UISearchBarExtensions.swift 63.63% <0%> (ø)
...ources/SwifterSwift/UIKit/UISliderExtensions.swift 100% <0%> (ø)
...es/SwifterSwift/UIKit/UIScrollViewExtensions.swift 100% <0%> (ø)
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 96bc2a1...28e84bc. Read the comment docs.

moritzsternemann

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

<!-- 0 Errors 0 Warnings 4 Messages: Thank you for submitting a pul... 0 Markdowns --> <table> <thead> <tr> <th width="50"></th> <th width="100%" data-danger-table="true" data-kind="Message"> 4 Messages </th> </tr> </thead> <tbody> <tr> <td>:book:</td> <td data-sticky="false">Thank you for submitting a pull request to SwifterSwift. The team will review your submission as soon as possible.</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">iOS: Executed 599 tests, with 0 failures (0 unexpected) in 13.551 (15.950) seconds</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">tvOS: Executed 574 tests, with 0 failures (0 unexpected) in 4.500 (7.206) seconds</td> </tr> <tr> <td>:book:</td> <td data-sticky="false">macOS: Executed 431 tests, with 0 failures (0 unexpected) in 1.247 (1.631) seconds</td> </tr> </tbody> </table>

<p align="right" data-meta="generated_by_danger"> Generated by :no_entry_sign: <a href="https://danger.systems/">Danger</a> </p>

moritzsternemann

comment created time in 2 days

PR opened SwifterSwift/SwifterSwift

Add sum(for keyPath:) to Sequence

🚀 Sum up a Numeric property, referenced by KeyPath, of all elements in a sequence. Originally from https://swiftbysundell.com/articles/reducers-in-swift/.

Checklist

<!--- Please go over all the following points, and put an x in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

  • [x] I checked the Contributing Guidelines before creating this request.
  • [x] New extensions are written in Swift 5.0.
  • [x] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+, or use @available if not.
  • [x] I have added tests for new extensions, and they passed.
  • [x] All extensions have a clear comments explaining their functionality, all parameters and return type in English.
  • [x] All extensions are declared as public.
  • [ ] I have added a changelog entry describing my changes.
+18 -0

0 comment

2 changed files

pr created time in 2 days

startedSwifterSwift/SwifterSwift

started time in 2 days

fork moritzsternemann/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in 2 days

issue commentSwifterSwift/SwifterSwift

Extend Sequence to get sum by keypath

I'd like to work on this task 😃 can you assign it to me?

omaralbeik

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS) && !os(Linux)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let colors: [UIColor] = [.red, .blue, .orange, .yellow]+        let locations: [CGFloat]? = nil+        let startPoint = CGPoint(x: 0.0, y: 0.5)+        let endPoint = CGPoint(x: 1.0, y: 0.5)+        let gradientLayerType: CAGradientLayerType = .axial++        let gradientLayer = CAGradientLayer(colors: colors, locations: locations, startPoint: startPoint, endPoint: endPoint, type: gradientLayerType)++        XCTAssertEqual(gradientLayer.colors?.count, colors.count)+        XCTAssertEqual(gradientLayer.locations as? [CGFloat], locations)

I had tried it with non-nil values and it worked fine.

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS) && !os(Linux)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let colors: [UIColor] = [.red, .blue, .orange, .yellow]+        let locations: [CGFloat]? = nil+        let startPoint = CGPoint(x: 0.0, y: 0.5)+        let endPoint = CGPoint(x: 1.0, y: 0.5)+        let gradientLayerType: CAGradientLayerType = .axial++        let gradientLayer = CAGradientLayer(colors: colors, locations: locations, startPoint: startPoint, endPoint: endPoint, type: gradientLayerType)++        XCTAssertEqual(gradientLayer.colors?.count, colors.count)+        XCTAssertEqual(gradientLayer.locations as? [CGFloat], locations)

This works for now because locations is nil, but you'll need to map the values

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS) && !os(Linux)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let colors: [UIColor] = [.red, .blue, .orange, .yellow]+        let locations: [CGFloat]? = nil+        let startPoint = CGPoint(x: 0.0, y: 0.5)+        let endPoint = CGPoint(x: 1.0, y: 0.5)+        let gradientLayerType: CAGradientLayerType = .axial
        let gradientLayerType = CAGradientLayerType.axial
JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS) && !os(Linux)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let colors: [UIColor] = [.red, .blue, .orange, .yellow]+        let locations: [CGFloat]? = nil

Test a non-nil value

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added "numberOfDaysLeftInYear" to "Date" extension

 final class DateExtensionsTests: XCTestCase {         let tomorrowCheck = Calendar.current.date(byAdding: .day, value: 1, to: date)         XCTAssertEqual(tomorrow, tomorrowCheck)     }++    func testDayInYear() {+        let date = Date()+        let dayInYear = date.dayInYear+        let dayInYearCheck = Calendar.current.ordinality(of: .day, in: .year, for: date)!+        XCTAssertEqual(dayInYear, dayInYearCheck)+    }++    func testNumberOfDaysInYear() {+        let date = Date()+        let numberOfDaysInYear = date.numberOfDaysInYear+        let numberOfDaysInYearCheck = (Calendar.current.range(of: .day, in: .year, for: date)!.upperBound) - 1+        XCTAssertEqual(numberOfDaysInYear, numberOfDaysInYearCheck)+    }++    func testnNmberOfDaysLeftInYear() {+        let date = Date()+        let dayLeftInAYear = date.numberOfDaysLeftInYear++        let dayInYear = Calendar.current.ordinality(of: .day, in: .year, for: date)!+        let numberOfDaysInYear = (Calendar.current.range(of: .day, in: .year, for: date)!.upperBound) - 1+        let dayLeftInAYearCheck = numberOfDaysInYear - dayInYear++        XCTAssertEqual(dayLeftInAYear, dayLeftInAYearCheck)+    }

@guykogus Many thanks for the comment! I'll re-write the tests to make it correct :)

Hero93

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@LucianoPAlmeida

Added the Linux check.

JayMehta97

comment created time in 2 days

issue openedSwifterSwift/SwifterSwift

Extend Sequence to get sum by keypath

Extend The Sequence type with a sum(for keyPath:) function to return the sum of nested number for all objects within a sequence

Examples from Swift by Sundell's article on reducers

let unreadCount = mailboxes.sum(for: \.unreadMessages.count)
let totalScore = levels.sum(for: \.playerScore)
let meetingDuration = today.meetings.sum(for: \.duration)

created time in 2 days

fork EliperlGit/SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

https://swifterswift.com

fork in 2 days

startedSwifterSwift/SwifterSwift

started time in 2 days

startedSwifterSwift/SwifterSwift

started time in 2 days

startedSwifterSwift/SwifterSwift

started time in 2 days

startedSwifterSwift/SwifterSwift

started time in 2 days

pull request commentSwifterSwift/SwifterSwift

🚀 UIGraphicsImageRenderer in filled(withColor:)

It's a shame watchOS support has to be dropped. Could you could copy the function and surround it with @available(watchOS, *) with the old implementation?

I bet I can actually configure the OS macro in such a way that it'll only compile the new way on platforms that're not watchOS. That way, we don't have to maintain basically the same code twice. I'll see if I can get that patched when I get home from work later

raysarebest

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added multipleCoordinateZoom extension to MapView

 final class MKMapViewTests: XCTestCase {         let annotationViewWithAnnotation = mapView.dequeueReusableAnnotationView(withClass: MKPinAnnotationView.self, for: annotation)         XCTAssertNotNil(annotationViewWithAnnotation)     }-+    +    func testWithEmptyItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let emptyItemArray: [CLLocationCoordinate2D] = []+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        +        let emptyItemInMapView: Void = mapView.zoom(to: emptyItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        +        XCTAssertNotNil(emptyItemInMapView)+    }+    +    func testWithOneItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let oneItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243)]+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        +        let oneItemInMapView: Void = mapView.zoom(to: oneItemArray, meter: meter, edgePadding: edgePadding, animated: true)+        XCTAssertNotNil(oneItemInMapView)+    }+    +    func testWithMultiItemArray() {+        let mapView = MKMapView()+        +        let meter = 500.0+        let edgePadding: UIEdgeInsets = .init(top: 50, left: 50, bottom: 50, right: 50)+        let multiItemArray: [CLLocationCoordinate2D] = [.init(latitude: 36.9751, longitude: 38.4243),+                                                        .init(latitude: 37.06622, longitude: 37.38332),+                                                        .init(latitude: 41.00527, longitude: 28.97696)]+        +        let multiItemInMapView: Void = mapView.zoom(to: multiItemArray, meter: meter, edgePadding: edgePadding, animated: true)

I think it is complaining about the trailing space in the line, not the line it self :) Sorry, didn't get you question about interpretation ... a got a bit lost here 😄

mustafagunes

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@JayMehta97 Lixux build is failing, in this case just as if !os(Linux) should be good :)

JayMehta97

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@guykogus

I have made all the suggested changes.

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let gradientLayer = CAGradientLayer(colors: [.red, .blue, .orange, .yellow], locations: nil, startPoint: CGPoint(x: 0.0, y: 0.5), endPoint: CGPoint(x: 1.0, y: 0.5), type: .axial)+

Sure

JayMehta97

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@JayMehta97 I think it's best to wait for this PR to be merged before creating the new one

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensionsTests.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++import XCTest+@testable import SwifterSwift++#if !os(watchOS)++final class CAGradientLayerExtensionsTests: XCTestCase {++    func testInitWithGradientAttributes() {+        let gradientLayer = CAGradientLayer(colors: [.red, .blue, .orange, .yellow], locations: nil, startPoint: CGPoint(x: 0.0, y: 0.5), endPoint: CGPoint(x: 1.0, y: 0.5), type: .axial)+

Please add tests to check the rest of the values

JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensions.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++#if !os(watchOS)++extension CAGradientLayer {++    /// SwifterSwift: Creates a CAGradientLayer with the specified colors, location, startPoint, endPoint, and type.+    /// - Parameter colors: An array of colors defining the color of each gradient stop+    /// - Parameter locations: An array of NSNumber defining the location of each+    ///                gradient stop as a value in the range [0,1]. The values must be+    ///                monotonically increasing. If a nil array is given, the stops are+    ///                assumed to spread uniformly across the [0,1] range. When rendered,+    ///                the colors are mapped to the output colorspace before being+    ///                interpolated. (default is nil)+    /// - Parameter startPoint: start point corresponds to the first gradient stop (I.e. [0,0] is the bottom-corner of the layer, [1,1] is the                          top-right corner.)
    /// - Parameter startPoint: start point corresponds to the first gradient stop (I.e. [0,0] is the bottom-corner of the layer, [1,1] is the top-right corner.)
JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

 The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S   - Added `enumerateMatches(in:options:range:using:)`, `matches(in:options:range:)`, `numberOfMatches(in:options:range:)`, `firstMatch(in:options:range:)`, `rangeOfFirstMatch(in:options:range:)`, `stringByReplacingMatches(in:options:range:withTemplate:)`, `replaceMatches(in:options:range:withTemplate:)`, which use `String` and `String.Range` in place of `NSString` and `NSRange` to make the calls Swifter. [#727](https://github.com/SwifterSwift/SwifterSwift/pull/727) by [guykogus](https://github.com/guykogus). - **UIImage**:   - Added `withBackgroundColor(_:)` to specify a background color for a partially transparent image. [#721](https://github.com/SwifterSwift/SwifterSwift/pull/721) by [MaxHaertwig](https://github.com/maxhaertwig).+  - **CAGradientLayer**:
- **CAGradientLayer**:
JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

 The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S   - Added `enumerateMatches(in:options:range:using:)`, `matches(in:options:range:)`, `numberOfMatches(in:options:range:)`, `firstMatch(in:options:range:)`, `rangeOfFirstMatch(in:options:range:)`, `stringByReplacingMatches(in:options:range:withTemplate:)`, `replaceMatches(in:options:range:withTemplate:)`, which use `String` and `String.Range` in place of `NSString` and `NSRange` to make the calls Swifter. [#727](https://github.com/SwifterSwift/SwifterSwift/pull/727) by [guykogus](https://github.com/guykogus). - **UIImage**:   - Added `withBackgroundColor(_:)` to specify a background color for a partially transparent image. [#721](https://github.com/SwifterSwift/SwifterSwift/pull/721) by [MaxHaertwig](https://github.com/maxhaertwig).+  - **CAGradientLayer**:+    - Added `init(colors:locations:startPoint:endPoint:type:)` convenience initializers. [#726](https://github.com/SwifterSwift/SwifterSwift/pull/726) by [JayMehta97](https://github.com/JayMehta97).
  - Added `init(colors:locations:startPoint:endPoint:type:)` convenience initializer. [#726](https://github.com/SwifterSwift/SwifterSwift/pull/726) by [JayMehta97](https://github.com/JayMehta97).
JayMehta97

comment created time in 2 days

Pull request review commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

+//+//  CAGradientLayerExtensions.swift+//  SwifterSwift+//+//  Created by Jay Mehta on 11/10/19.+//  Copyright © 2019 SwifterSwift+//++#if !os(watchOS)++extension CAGradientLayer {++    /// SwifterSwift: Creates a CAGradientLayer with the specified colors, location, startPoint, endPoint, and type.+    /// - Parameter colors: An array of colors defining the color of each gradient stop+    /// - Parameter locations: An array of NSNumber defining the location of each+    ///                gradient stop as a value in the range [0,1]. The values must be+    ///                monotonically increasing. If a nil array is given, the stops are+    ///                assumed to spread uniformly across the [0,1] range. When rendered,+    ///                the colors are mapped to the output colorspace before being+    ///                interpolated. (default is nil)+    /// - Parameter startPoint: start point corresponds to the first gradient stop (I.e. [0,0] is the bottom-corner of the layer, [1,1] is the                          top-right corner.)+    /// - Parameter endPoint: end point corresponds to the last gradient stop+    /// - Parameter type: The kind of gradient that will be drawn. Currently, the only allowed values are `axial' (the default value),                            `radial', and `conic'.
    /// - Parameter type: The kind of gradient that will be drawn. Currently, the only allowed values are `axial' (the default value), `radial', and `conic'.
JayMehta97

comment created time in 2 days

pull request commentSwifterSwift/SwifterSwift

Added 'applyGradient' method to UIViewExtensions

@LucianoPAlmeida @guykogus

Should I open another PR?

JayMehta97

comment created time in 2 days

startedSwifterSwift/SwifterSwift

started time in 3 days

Pull request review commentSwifterSwift/SwifterSwift

Added "numberOfDaysLeftInYear" to "Date" extension

 final class DateExtensionsTests: XCTestCase {         let tomorrowCheck = Calendar.current.date(byAdding: .day, value: 1, to: date)         XCTAssertEqual(tomorrow, tomorrowCheck)     }++    func testDayInYear() {+        let date = Date()+        let dayInYear = date.dayInYear+        let dayInYearCheck = Calendar.current.ordinality(of: .day, in: .year, for: date)!+        XCTAssertEqual(dayInYear, dayInYearCheck)+    }++    func testNumberOfDaysInYear() {+        let date = Date()+        let numberOfDaysInYear = date.numberOfDaysInYear+        let numberOfDaysInYearCheck = (Calendar.current.range(of: .day, in: .year, for: date)!.upperBound) - 1+        XCTAssertEqual(numberOfDaysInYear, numberOfDaysInYearCheck)+    }++    func testnNmberOfDaysLeftInYear() {+        let date = Date()+        let dayLeftInAYear = date.numberOfDaysLeftInYear++        let dayInYear = Calendar.current.ordinality(of: .day, in: .year, for: date)!+        let numberOfDaysInYear = (Calendar.current.range(of: .day, in: .year, for: date)!.upperBound) - 1+        let dayLeftInAYearCheck = numberOfDaysInYear - dayInYear++        XCTAssertEqual(dayLeftInAYear, dayLeftInAYearCheck)+    }

+1 Here

Hero93

comment created time in 3 days

startedSwifterSwift/SwifterSwift

started time in 3 days

startedSwifterSwift/SwifterSwift

started time in 3 days

more