-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
492 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import CoreGraphics | ||
|
||
public extension CGPoint { | ||
|
||
/// Offset point by new x and y | ||
/// - Parameters: | ||
/// - x: x | ||
/// - y: y | ||
/// - Returns: new point | ||
func offseted(x: CGFloat = 0.0, y: CGFloat = 0.0) -> CGPoint { | ||
var point = self | ||
point.x += x | ||
point.y += y | ||
return point | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import CoreGraphics | ||
|
||
public extension CGRect { | ||
|
||
var topLeft: CGPoint { | ||
return origin | ||
} | ||
|
||
var topRight: CGPoint { | ||
return CGPoint(x: maxX, y: minY) | ||
} | ||
|
||
var topMiddle: CGPoint { | ||
return CGPoint(x: midX, y: minY) | ||
} | ||
|
||
var bottomLeft: CGPoint { | ||
return CGPoint(x: minX, y: maxY) | ||
} | ||
|
||
var bottomRight: CGPoint { | ||
return CGPoint(x: maxX, y: maxY) | ||
} | ||
|
||
var bottomMiddle: CGPoint { | ||
return CGPoint(x: midX, y: maxY) | ||
} | ||
|
||
var leftMiddle: CGPoint { | ||
return CGPoint(x: minX, y: midY) | ||
} | ||
|
||
var rightMiddle: CGPoint { | ||
return CGPoint(x: maxX, y: midY) | ||
} | ||
|
||
var midX: CGFloat { | ||
return (maxX - minX) / 2 | ||
} | ||
|
||
var midY: CGFloat { | ||
return (maxY - minY) / 2 | ||
} | ||
|
||
/// Center taking size into account | ||
var center: CGPoint { | ||
get { | ||
let x = origin.x + size.width / 2 | ||
let y = origin.y + size.height / 2 | ||
return CGPoint(x: x, y: y) | ||
} | ||
set { | ||
origin.x = newValue.x - size.width / 2 | ||
origin.y = newValue.y - size.height / 2 | ||
} | ||
} | ||
|
||
var sameCenterSquare: CGRect { | ||
let maxLength = max(size.width, size.height) | ||
var rect = CGRect(x: 0, y: 0, width: maxLength, height: maxLength) | ||
rect.center = center | ||
return rect | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import CoreGraphics | ||
|
||
public func +(lhs: CGSize, rhs: CGSize) -> CGSize { | ||
return CGSize(width: lhs.width + rhs.width, height: lhs.height + rhs.height) | ||
} | ||
|
||
public func -(lhs: CGSize, rhs: CGSize) -> CGSize { | ||
return CGSize(width: lhs.width - rhs.width, height: lhs.height - rhs.height) | ||
} | ||
|
||
public func *(lhs: CGSize, rhs: CGFloat) -> CGSize { | ||
return CGSize(width: lhs.width * rhs, height: lhs.height * rhs) | ||
} | ||
|
||
public func /(lhs: CGSize, rhs: CGFloat) -> CGSize { | ||
return CGSize(width: lhs.width / rhs, height: lhs.height / rhs) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Foundation | ||
|
||
public extension Array where Element: Equatable { | ||
|
||
/// Removes the given element in the array. | ||
/// | ||
/// - Parameter element: The element to be removed. | ||
/// - Returns: The element got removed, or `nil` if the element doesn't exist. | ||
@discardableResult | ||
mutating func remove(_ element: Element) -> Element? { | ||
if let index = self.firstIndex(of: element) { | ||
return self.remove(at: index) | ||
} | ||
return nil | ||
} | ||
|
||
/// Returns an array where repeating elements of the receiver got removed. | ||
var removingRepeatElements: Array<Element> { | ||
var arr = Array<Element>() | ||
forEach { | ||
if !arr.contains($0) { | ||
arr.append($0) | ||
} | ||
} | ||
return arr | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Foundation | ||
|
||
public extension CFRunLoopTimer { | ||
|
||
/// Invalidate CFRunLoopTimer | ||
func invalidate() { | ||
CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), self, .commonModes) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Foundation | ||
|
||
public extension Collection { | ||
|
||
/// Safe indexing. | ||
/// Returns the element at the specified index iff it is within bounds, otherwise nil. | ||
/// ref: https://stackoverflow.com/questions/25329186/safe-bounds-checked-array-lookup-in-swift-through-optional-bindings | ||
/// | ||
/// - Parameter index: The index used to retrieve a value / an object. | ||
subscript (safe index: Index) -> Element? { | ||
return indices.contains(index) ? self[index] : nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Foundation | ||
|
||
public extension Data { | ||
/// Returns a string of hex value. | ||
var hexString: String { | ||
return withUnsafeBytes { (bytes: UnsafeRawBufferPointer) -> String in | ||
let buffer = bytes.bindMemory(to: UInt8.self) | ||
return buffer.map {String(format: "%02hhx", $0)}.reduce("", { $0 + $1 }) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import Foundation | ||
|
||
public extension Date { | ||
|
||
/// Days of the week in Gregorian calendar (Sunday - Saturday) | ||
static let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] | ||
|
||
/// Current day of the week in Gregorian calendar | ||
var day: String { | ||
let gregorian = Calendar(identifier: .gregorian) | ||
let weekday = gregorian.component(.weekday, from: self) | ||
return Date.days[weekday] | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import Foundation | ||
|
||
public extension FileManager { | ||
|
||
/// Size of file at path | ||
/// | ||
/// - Parameter path: file path | ||
/// - Returns: Size in bytes | ||
func fileSize(atPath path: String) -> Int { | ||
let attributes = try? attributesOfItem(atPath: path) | ||
return (attributes?[FileAttributeKey.size] as? Int) ?? 0 | ||
} | ||
|
||
/// Size of folder | ||
/// | ||
/// - Parameter path: folder path | ||
/// - Returns: size in bytes | ||
func folderSize(atPath path: String) -> Int { | ||
let manager = FileManager.default | ||
if manager.fileExists(atPath: path) { | ||
do { | ||
let childFilesEnumerator = try (manager.subpathsOfDirectory(atPath: path) as NSArray).objectEnumerator() | ||
var folderSize = 0 | ||
while childFilesEnumerator.nextObject() != nil { | ||
if let fileName = childFilesEnumerator.nextObject() as? String, | ||
let url = URL(string: path) { | ||
let fileAbsolutePath = url.appendingPathComponent(fileName).absoluteString | ||
folderSize += self.fileSize(atPath: fileAbsolutePath) | ||
} | ||
} | ||
return folderSize | ||
|
||
} catch { | ||
dprint(error) | ||
} | ||
} | ||
return 0 | ||
} | ||
|
||
|
||
/// Size of directory at URL | ||
/// | ||
/// - Parameter URL: URL | ||
/// - Returns: Size in bytes | ||
func directorySize(at URL: URL) -> Int { | ||
var result = 0 | ||
let properties = [URLResourceKey.localizedNameKey, URLResourceKey.creationDateKey, URLResourceKey.localizedTypeDescriptionKey] | ||
let manager = FileManager.default | ||
do { | ||
let urls = try manager.contentsOfDirectory(at: URL, includingPropertiesForKeys: properties, options: .skipsHiddenFiles) | ||
for fileSystemItem in urls { | ||
var directory: ObjCBool = false | ||
let path = fileSystemItem.path | ||
manager.fileExists(atPath: path, isDirectory: &directory) | ||
if directory.boolValue { | ||
result += directorySize(at: fileSystemItem) | ||
} else { | ||
result += try manager.attributesOfItem(atPath: path)[FileAttributeKey.size] as! Int | ||
} | ||
} | ||
|
||
} catch { | ||
dprint("Error: \(error)") | ||
} | ||
return result | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Foundation | ||
|
||
/// AppVersion set in `CFBundleShortVersionString` | ||
public var appVersion: String { | ||
return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String | ||
} | ||
|
||
/// Languages set in user defaults key `AppleLanguages` | ||
public var systemLanguages: [String] { | ||
return UserDefaults.standard.stringArray(forKey: "AppleLanguages") ?? [] | ||
} | ||
|
||
/// Sleeps the thread | ||
/// - Parameter duration: in seconds | ||
public func sleep(duration: TimeInterval) { | ||
#if DEBUG | ||
Thread.sleep(forTimeInterval: duration) | ||
#endif | ||
} | ||
|
||
/// Swift still calls `print()` and/or `debugPrint()` in shipped apps. | ||
/// We use a method described in onevcat's post (https://onevcat.com/2016/02/swift-performance/) | ||
/// to optimaze the performance. | ||
/// | ||
/// - Parameter item: items to print | ||
public func dprint(_ item: @autoclosure () -> Any) { | ||
#if DEBUG | ||
print(item()) | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import Foundation | ||
|
||
public extension Int { | ||
|
||
/// Whether self is an odd number | ||
var isOdd: Bool { | ||
return !isEven | ||
} | ||
|
||
/// Whether self is an even number | ||
var isEven: Bool { | ||
return self % 2 == 0 | ||
} | ||
|
||
/// Treats 0 as nil | ||
var nilIfZero: Int? { | ||
if self == 0 { return nil } | ||
return self | ||
} | ||
|
||
/// Make the number to string | ||
var string: String { | ||
return String(self) | ||
} | ||
|
||
/// Make a range from zero to self | ||
var range: CountableRange<Int> { | ||
return 0..<self | ||
} | ||
|
||
/// Return a number of instances | ||
/// | ||
/// - Parameter creation: The initialization of the object | ||
/// - Returns: An array containing the objects | ||
func instances<T>(of creation: @autoclosure () throws -> T) rethrows -> [T] { | ||
return try (0 ..< self).map { _ in | ||
try creation() | ||
} | ||
} | ||
|
||
/// Return if `self` is in the given range. | ||
/// | ||
/// - Parameter range: Target range. | ||
/// - Returns: `true` if self is in the range, otherwise `false`. | ||
func inRange(_ range: Range<Int>) -> Bool { | ||
return range.contains(self) | ||
} | ||
|
||
|
||
// minutes to seconds | ||
var minutes: Int { | ||
return self * 60 | ||
} | ||
|
||
// hours to seconds | ||
var hours: Int { | ||
return (self * 60).minutes | ||
} | ||
|
||
var days: Int { | ||
return (self * 24).hours | ||
} | ||
|
||
var months: Int { | ||
return (self * 30).days | ||
} | ||
|
||
var years: Int { | ||
return (self * 12).months | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Foundation | ||
|
||
public extension NSObject { | ||
|
||
/// Exchange two implementations of the given selectors, aka method swizzling. | ||
/// | ||
/// - Parameters: | ||
/// - originalSelector: The original selector. | ||
/// - swizzledSelector: Another selector. | ||
class func exchangeImplementations(originalSelector: Selector, swizzledSelector: Selector) { | ||
guard | ||
let originalMethod = class_getInstanceMethod(self, originalSelector), | ||
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) | ||
else { | ||
dprint("Error: Unable to exchange method implemenation!!") | ||
return | ||
} | ||
method_exchangeImplementations(originalMethod, swizzledMethod) | ||
} | ||
|
||
/// Return class name. | ||
var className: String { | ||
return type(of: self).description().components(separatedBy: ".").last ?? "" | ||
} | ||
|
||
/// Print the deinitialization message of self. | ||
final func printDeinitMessage() { | ||
dprint("Deinit Message: \(className): \(self)") | ||
} | ||
|
||
} |
Oops, something went wrong.