Giter Site home page Giter Site logo

handyswift's Introduction

HandySwift

The goal of this library is to provide handy features that didn't make it into the Swift standard library (yet).

Checkout HandySwiftUI for handy UI features that should have been part of SwiftUI in the first place.

Documentation

Learn how you can make the most of HandySwift by reading the guides inside the documentation:

📖 Open HandySwift Documentation

Showcase

I extracted most of this library from these Indie apps (rate them with 5 stars to support me!):

App Icon App Name & Description Supported Platforms
TranslateKit: App Localizer
Simple drag & drop translation of String Catalog files with support for 4 machine translation services.
Mac
FreelanceKit: Time Tracking
Simple & affordable time tracking with a native experience for all  devices. iCloud sync & CSV export included.
iPhone, iPad, Mac, Vision
CrossCraft: Custom Crosswords
Create themed & personalized crosswords. Solve them yourself or share them to challenge others.
iPhone, iPad, Mac, Vision
FocusBeats: Pomodoro + Music
Deep Focus with proven Pomodoro method & select Apple Music playlists & themes. Automatically pauses music during breaks.
iPhone, iPad, Mac, Vision
Guided Guest Mode
Showcase Apple Vision Pro effortlessly to friends & family. Customizable, easy-to-use guides for everyone!
Vision
Posters: Discover Movies at Home
Auto-updating & interactive posters for your home with trailers, showtimes, and links to streaming services.
Vision

handyswift's People

Contributors

fredpi avatar jeehut avatar knothed avatar lf-araujo avatar lukemmtt avatar mrylmz avatar muescha avatar raberm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

handyswift's Issues

Podspec: pod lib lint doesn't work (v1.2.0)

Unfortunately the Cocoapods installation method won't install v1.2.0 right now since the Podspec seems to be broken. The issue is that I'm using AppKit on the OS X target which doesn't seem to be recognized by Cocoapods even after explicitly listing it.

Output:

$ pod lib lint

 -> HandySwift (1.2.0)
    - ERROR | xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
    - ERROR | xcodebuild:  /Users/Dschee/Code/Flinesoft/ApplePlatforms/HandySwift/Sources/Extensions/CoreGraphicsExtensions.swift:75:12: error: no such module 'AppKit'
    - NOTE  | xcodebuild:  clang: error: linker command failed with exit code 1 (use -v to see invocation)
    - NOTE  | [iOS] xcodebuild:  fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Intermediates/Pods.build/Release-iphonesimulator/HandySwift.build/Objects-normal/i386/HandySwift (No such file or directory)
    - NOTE  | [iOS] xcodebuild:  error: cannot parse the debug map for "/Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-iphonesimulator/HandySwift/HandySwift.framework/HandySwift": No such file or directory
    - ERROR | xcodebuild:  /Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-iphonesimulator/HandySwift/HandySwift.framework/Modules/module.modulemap:9:12: error: header 'HandySwift-Swift.h' not found
    - ERROR | xcodebuild:  /var/folders/c1/slwc_7ln1wq8kq619bcc33h40000gn/T/CocoaPods/Lint/App/main.swift:1:8: error: could not build Objective-C module 'HandySwift'
    - NOTE  | [iOS] xcodebuild:  fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Intermediates/App.build/Release-iphonesimulator/App.build/Objects-normal/i386/App (No such file or directory)
    - NOTE  | [iOS] xcodebuild:  error: cannot parse the debug map for "/Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-iphonesimulator/App.app/App": No such file or directory
    - NOTE  | [tvOS] xcodebuild:  error: cannot parse the debug map for "/Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-appletvsimulator/HandySwift/HandySwift.framework/HandySwift": No such file or directory
    - ERROR | [tvOS] xcodebuild:  /Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-appletvsimulator/HandySwift/HandySwift.framework/Modules/module.modulemap:9:12: error: header 'HandySwift-Swift.h' not found
    - NOTE  | [tvOS] xcodebuild:  error: cannot parse the debug map for "/Users/Dschee/Library/Developer/Xcode/DerivedData/App-criesqgevvftrmciwougseuwlluo/Build/Products/Release-appletvsimulator/App.app/App": No such file or directory

Add =~ operator for regex check

I suggest to add a new infix operator =~ for checking whether a string matches a regex using the following implementation:

infix operator =~
func =~ (lhs: String, rhs: String) -> Bool {
    return lhs.range(of: rhs, options: .regularExpression) == lhs.range(of: lhs)
}

Use:

let stringMatchesRegex = "ABC" =~ "[A-Z]+"

Add Memo, Mutable

I suggest adding the Memo Type to HandySwift, based on this repo.

My suggested implementation adjusting the implementation a bit can be found here.

Implement `average()` for more numeric types

Currently, func average() -> Double is defined as an extension on Collection where Element == Double. What about CGFloats?

I suggest to add a protocol Field (based on algebraic fields) providing addition, multiplication and division with Self elements, and also a zero and one element. This would allow both average() and sum() to be implemented more generically. Double, Float and CGFloat could conform to this protocol (with nearly no additional implementation effort).

The integer case would have to be treated specially though.

Optimize HandySwift for performance-critical code

When using HandySwift in performance-critical code, I noticed a bottleneck arising through the missing inlinability of (trivial) HandySwift methods. Because HandySwift's trivial methods (e.g. Int.timesMake) live in another (already compiled) module than the client code, the client compiler cannot inline and optimize these methods. It turned out that reimplementing Int.timesMake myself and putting in the same module was significantly (!) faster than using HandySwift's Int.timesMake.

To be specific, the range-map combination of Int.timesMake ((0 ..< n).map { _ in closure() }) results in cumbersome compiled code which cannot / is not optimized away during HandySwift's compilation, and will therefore always be a performance burden for the client.

Compiled code of HandySwift's Int.timesMake

As Swift strives to be a performant language, very many of Swift's stdlib-implementations are actually annotated with @inlinable or even @_transparent to allow the client compiler to perform inlining and subsequent dataflow-analysis and (aggressive) optimizations.
Examples: Array, Range

Therefore, I propose to add @inlinable or @_transparent to relevant HandySwift methods. These include all Array- / Dictionary- / Collection- / Range-related methods.

Unowned issue

Hello there!

There's some error in the library's playground in those lines (317-321):

//: ## Unowned
//: `Unowned` is a wrapper to store unowned references to a `Wrapped` instance.
//: ### Unowned(_:)
//: Initialize with an object reference.
var unowned = Unowned(text)  // error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x60400003f4).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

I've checked, the text variable is still available.

I also copied the unowned file to my project and tested. Still got an error but in another place:

        let text = NSString(string: "Hello!")
        let unowned = Unowned(text)
        print(unowned.value)  // "Hello!"
        print(unowned)  // Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

Not sure about the nature of this.

Changing hue in hsba on a white color doesn't work

Regarding the following code:

let newHueValue = UIColor.white.change(.hue, to: 0.25).hsba.hue

The expected new hue value would be 0.25, but it's actually 0.0. It seems not to work with UIColor.white. This should be added to the tests and covered. Also other possible not-working options should checked like UIColor.black.

Change default violation level to warning

Problem Statement

Currently it's error which makes builds fail when running via Xcode build script. And there's not even an option like --lenient to downgrade errors to warnings.

Suggested Solution

Just default to the warning level instead of error like now.

Add Weak

I suggest adding a Weak wrapper alongside the Mutable wrapper requested here.

Suggested Implementation can be found here.

UIKIT define

HandySwift sets OTHER_SWIFT_FLAGS = "-D UIKIT"; on the project file, then checking with #if UIKIT.
This version might be easier to handle as it needs no flags (Cocoapods didn't set it up for me, fe)

#if os(iOS) || os(tvOS)

Update to comply with new renaming conventions in Swift 3

For example considering this (as of current HandySwift):

" \t BB-8 likes Rey \t ".strip

As this is creating a new String object it should probably named stripped and should probably implemented as a function resulting to this:

" \t BB-8 likes Rey \t ".stripped()

This is a breaking change though, therefore a major update would be necessary.

Make the `.sum` function more generic

Problem Statement

Currently only works on Numeric types.

Suggested Solution

Could be made available for all AdditiveArithmetic types:

extension Sequence where Element: AdditiveArithmetic {
  public func sum() -> Element {
    reduce(.zero, +)
  }
}

Also, a predicate could be added like suggested here.

String isNilOrEmpty

Sometimes, when dealing with viewModels with contain optional values, I find myself writing code like this:

if (viewModel.text ?? "").isEmpty { ... }

An equivalent alternative is this:

if viewModel.text?.count > 0 { ... }

Still, I think it is not as concise as it should be.

C# provides a method String.IsNullOrEmpty. What do you think about a respective Swift method? E.g. an extension to Optional where Wrapped == StringProtocol providing a property isNilOrEmpty?

Also, because HandySwift already provides an isBlank property, this could be extended to also provide a isNilOrBlank property, if this is a common use-case.

Carthage update failed with Xcode 8 / Swift 2.3

The following build commands failed:
CompileSwift normal arm64 /Checkouts/HandySwift/Sources/Structs/FrequencyTable.swift
CompileSwift normal arm64 /Checkouts/HandySwift/Sources/Globals.swift
CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
(3 failures)

Embrace the new Swift Algorithms package

Problem Statement

Currently, several algorithmic helpers are added to HandySwift. There's is now a new Algorithms package though.

Suggested Solution

As there's now an official "Algorithms" package, we should deprecate the HandySwift helpers and help migrate to the new Algorithms package with the right pointers.

We could both, make use of the Algorithms package and also remove helpers and point to available method in it.

Another think we might do is actually provide some helpers from HandySwift and add them to the Algorithms package itself.

Support Xcode 10.2 or Update CI

I noticed that the CI emitted an error for the most recent commit on stable (cba3181) with the following cause:
image

Omitting the return statement for single-line functions is a feature since Swift 5.1. The CI is currently using Xcode 10.2.x (which is deprecated on bitrise anyway), which means a Swift version < 5.1.

This means, either the CI should be configured to use a more recent version of Xcode and Swift, or single-line return statements should use an explicit return to allow compatibility with Xcode 10.2.x.

Withable not working on custom types with init parameters

Expected Behavior

When I have a Task type like so:

class Task: Withable {
    var name: String
    var absolutePriority: UInt64? = nil
}

I should be able to write code like this:

let tasks: [Task] = [
    SingleTask(name: "Task1").with { $0.absolutePriority = -100 },
    SingleTask(name: "Task2").with { $0.absolutePriority = -50 },
    SingleTask(name: "Task3").with { $0.absolutePriority = 0 },
    SingleTask(name: "Task4").with { $0.absolutePriority = 25 },
    SingleTask(name: "Task5").with { $0.absolutePriority = 50 },
]

Actual Behavior

It's not building because Withable requires my type not not have any parameters in the init method, which shouldn't be the case.

Steps to Reproduce the Problem

See code above.

Specifications

  • Version: 3.2.0
  • Platform: macOS 10.15.4
  • IDE Version: Xcode 11.5

[Request] Periodic closure execution

Like setInterval in JavaScript. This would be extremely handy in some cases (in my particular case I use this for server logic). The syntax could be smth like this:

every(.seconds(5), dispatchLevel: .userInteractive) { /* closure body */ }

(this is done, ofc, with DispatchSource.makeTimerSource.scheduleRepeating)

File headers don't match shared format

Some file headers match the old file header format, e. g.:

//
//  Unowned.swift
//  HandySwift
//
//  Created by Murat Yilmaz on 19.05.18.
//  Copyright © 2018 Flinesoft. All rights reserved.
//

instead of:

//
//  Created by Murat Yilmaz on 19.05.18.
//  Copyright © 2018 Flinesoft. All rights reserved.
//

Is this intentional, or should we adjust old headers to the new format?

Add Comparable.bounded(lower:upper:) interface

I suggest to add the following extension to Comparable:

public extension Comparable {
    func bounded(lower: Self, upper: Self) -> Self {
        return min(upper, max(lower, self))
    }
}

Usage

let myInt = 5
let boundedInt = myInt.bounded(lower: 2, upper: 4)
print(boundedInt) // 4

Motivation

I often need to limit a value, and currently, I always use the min, max pattern also used within the bounded(lower:upper:) implementation. Using the new interface will make things fast to write and clear to understand, this is why I suggest to add it to HandySwift. As per the naming: We could also name it differently, e. g. limited.

Xcode 10 complains about String extensions

Seems like Xcode 10 with newer swift version complains about the following code:

public enum AllowedCharacters {
case numeric
case alphabetic
case alphaNumeric
case allCharactersIn(String). // Identifier Name Violation: Enum element name should only contain alphanumeric characters: 'allCharactersIn(_:)' (identifier_name)
}

resulting in not working:

case .allCharactersIn(let allowedCharactersString):
return allowedCharactersString
}
}()

Swift3 on CocoaPods?

I tried using pod "HandySwift", "~> 1.3". But did not work. Have you updated this version to cocoapods?

Add support for CocoaPods

Currently installation is only possible manually or via Carthage. CocoaPods is still in use in many projects and by many people so support for it should be given in any good Swift project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.