Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Hamad Fuad committed Apr 14, 2022
1 parent 3032406 commit 8ac172f
Show file tree
Hide file tree
Showing 18 changed files with 677 additions and 9 deletions.
4 changes: 3 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PackageDescription

let package = Package(
name: "SwiftExtensions",
platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8), .tvOS(.v15)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
Expand All @@ -20,7 +21,8 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "SwiftExtensions",
dependencies: []),
dependencies: [],
path: "Sources"),
.testTarget(
name: "SwiftExtensionsTests",
dependencies: ["SwiftExtensions"]),
Expand Down
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# SwiftExtensions

A description of this package.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![SPM compatible](https://img.shields.io/badge/SPM-Compatible-brightgreen.svg?style=flat)](https://swift.org/package-manager/)
[![Swift](https://img.shields.io/badge/Swift-5.6-orange.svg)](https://swift.org)
[![Xcode](https://img.shields.io/badge/Xcode-13.3-blue.svg)](https://developer.apple.com/xcode)
![Issues](https://img.shields.io/github/issues/ihamadfuad/SwiftExtensions)
![Releases](https://img.shields.io/github/v/release/ihamadfuad/SwiftExtensions)

# Sponsor
[![Sponsor](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/nuralme?country.x=BH&locale.x=en_US)

# AppStoreReviewsAPI

A Swift 5.6 implementation of native extensions for iOS, macOS, tvOS, watchOS.

## Installation
### Swift Package Manager (SPM)

You can use The Swift Package Manager to install SwiftEmailValidator by adding it to your Package.swift file:

import PackageDescription

let package = Package(
name: "MyApp",
targets: [],
dependencies: [
.Package(url: "https://github.com/ihamadfuad/SwiftExtensions.git", .from: "1.0.0")
]
)
35 changes: 35 additions & 0 deletions Sources/SwiftExtensions/Extensions/Character.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Character.swift
//
//
// Created by Hamad Ali on 14/04/2022.
//

import Foundation

public extension Character {

var isEmoji: Bool {

let scalarValue = String(self).unicodeScalars.first!.value

switch scalarValue {
case 0x1F600...0x1F64F, // Emoticons
0x1F300...0x1F5FF, // Misc Symbols and Pictographs
0x1F680...0x1F6FF, // Transport and Map
0x1F1E6...0x1F1FF, // Regional country flags
0x2600...0x26FF, // Misc symbols
0x2700...0x27BF, // Dingbats
0xE0020...0xE007F, // Tags
0xFE00...0xFE0F, // Variation Selectors
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
127_000...127_600, // Various asian characters
65024...65039, // Variation selector
9100...9300, // Misc items
8400...8447: // Combining Diacritical Marks for Symbols
return true
default:
return false
}
}
}
17 changes: 17 additions & 0 deletions Sources/SwiftExtensions/Extensions/Collection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation

public extension Collection {

var hasElements: Bool {

!isEmpty
}
}

public extension Collection {

subscript (safe index: Index) -> Element? {

indices.contains(index) ? self[index] : nil
}
}
19 changes: 19 additions & 0 deletions Sources/SwiftExtensions/Extensions/Data.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Data.swift
//
//
// Created by Hamad Ali on 14/04/2022.
//

import Foundation

public extension Data {

func string(encoding: String.Encoding) -> String? {
String(data: self, encoding: encoding)
}

func json(options: JSONSerialization.ReadingOptions = []) throws -> Any {
try JSONSerialization.jsonObject(with: self, options: options)
}
}
233 changes: 233 additions & 0 deletions Sources/SwiftExtensions/Extensions/Date.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
//
// Date.swift
//
//
// Created by Hamad Ali on 14/04/2022.
//

import Foundation

/// Convenience comparable
public extension Date {

func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool {

if includeBounds {
return startDate.compare(self).rawValue * compare(endDate).rawValue >= 0
}

return startDate.compare(self).rawValue * compare(endDate).rawValue > 0
}

var isInFuture: Bool {
self > Date()
}

var isInPast: Bool {
self < Date()
}

var isInToday: Bool {
Calendar.current.isDateInToday(self)
}

var isInYesterday: Bool {
Calendar.current.isDateInYesterday(self)
}

var isInTomorrow: Bool {
Calendar.current.isDateInTomorrow(self)
}

var isInCurrentWeek: Bool {
Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear)
}

var isInCurrentMonth: Bool {
Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month)
}

var isInCurrentYear: Bool {
return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year)
}
}

/// Convenience get
public extension Date {

/// Number of day in the current week.
var weekday: Int {
return Calendar.current.component(.weekday, from: self)
}

/// Number of week in the month.
var weekOfMonth: Int {
return Calendar.current.component(.weekOfMonth, from: self)
}

/// Number of week in the year.
var weekOfYear: Int {
return Calendar.current.component(.weekOfYear, from: self)
}

var yesterday: Date {
Calendar.current.date(byAdding: .day, value: -1, to: self) ?? Date()
}

var tomorrow: Date {
Calendar.current.date(byAdding: .day, value: 1, to: self) ?? Date()
}
}

/// Convenience set/get
public extension Date {

/// Get and set second
var second: Int {

get {
return Calendar.current.component(.second, from: self)
}
set {
let allowedRange = Calendar.current.range(of: .second, in: .minute, for: self)!
guard allowedRange.contains(newValue) else { return }

let currentSeconds = Calendar.current.component(.second, from: self)
let secondsToAdd = newValue - currentSeconds
if let date = Calendar.current.date(byAdding: .second, value: secondsToAdd, to: self) {
self = date
}
}
}

/// Get and set minute
var minute: Int {

get {
return Calendar.current.component(.minute, from: self)
}
set {

let allowedRange = Calendar.current.range(of: .minute, in: .hour, for: self)!

guard allowedRange.contains(newValue)
else {
return
}

let currentMinutes = Calendar.current.component(.minute, from: self)
let minutesToAdd = newValue - currentMinutes

if let date = Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) {

self = date
}
}
}

/// Get and set hour
var hour: Int {

get {
return Calendar.current.component(.hour, from: self)
}
set {

let allowedRange = Calendar.current.range(of: .hour, in: .day, for: self)!

guard allowedRange.contains(newValue)
else {
return
}

let currentHour = Calendar.current.component(.hour, from: self)
let hoursToAdd = newValue - currentHour

if let date = Calendar.current.date(byAdding: .hour, value: hoursToAdd, to: self) {

self = date
}
}
}

/// Get and set day
var day: Int {

get {
return Calendar.current.component(.day, from: self)
}
set {

let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)!

guard allowedRange.contains(newValue)
else {
return
}

let currentDay = Calendar.current.component(.day, from: self)
let daysToAdd = newValue - currentDay

if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) {

self = date
}
}
}

/// Get and set month
var month: Int {

get {
return Calendar.current.component(.month, from: self)
}
set {

let allowedRange = Calendar.current.range(of: .month, in: .year, for: self)!

guard allowedRange.contains(newValue)
else {
return
}

let currentMonth = Calendar.current.component(.month, from: self)
let monthsToAdd = newValue - currentMonth

if let date = Calendar.current.date(byAdding: .month, value: monthsToAdd, to: self) {

self = date
}
}
}

/// Get and set year
var year: Int {

get {
return Calendar.current.component(.year, from: self)
}
set {

guard newValue > 0
else {
return
}

let currentYear = Calendar.current.component(.year, from: self)
let yearsToAdd = newValue - currentYear

if let date = Calendar.current.date(byAdding: .year, value: yearsToAdd, to: self) {

self = date
}
}
}
}

/// Convenience calendar
public extension Date {

mutating func add(_ component: Calendar.Component, value: Int) {
self = Calendar.current.date(byAdding: component, value: value, to: self)!
}
}
14 changes: 14 additions & 0 deletions Sources/SwiftExtensions/Extensions/Debounced.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation

public func debounced(delay: TimeInterval,
queue: DispatchQueue = .main,
action: @escaping (() -> Void)) -> () -> Void {

var workItem: DispatchWorkItem?

return {
workItem?.cancel()
workItem = DispatchWorkItem(block: action)
queue.asyncAfter(deadline: .now() + delay, execute: workItem!)
}
}
17 changes: 17 additions & 0 deletions Sources/SwiftExtensions/Extensions/DispatchGroup.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation

public func dispatcher(enter: (VoidBlock) -> Void, _ main: @escaping VoidBlock) {

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()

enter({

dispatchGroup.leave()
})

dispatchGroup.notify(queue: .main) {
main()
}
}
Loading

0 comments on commit 8ac172f

Please sign in to comment.