diff --git a/AppleLibs.xcodeproj/project.pbxproj b/AppleLibs.xcodeproj/project.pbxproj index eb9467c1d867750d28bafcbf2284042ea58bdeb8..bd280baf49c0a224378f884109cd8fe5705ce11c 100644 --- a/AppleLibs.xcodeproj/project.pbxproj +++ b/AppleLibs.xcodeproj/project.pbxproj @@ -7,6 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + F623A64D2635B2B100F50371 /* Array+Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A64C2635B2B100F50371 /* Array+Extended.swift */; }; + F623A6562635B34100F50371 /* Sequence+Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A6552635B34100F50371 /* Sequence+Extended.swift */; }; + F623A65E2635B38200F50371 /* CharacterSet+Url.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A65D2635B38200F50371 /* CharacterSet+Url.swift */; }; + F623A6652635B3A800F50371 /* Dictornary+Url.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A6642635B3A800F50371 /* Dictornary+Url.swift */; }; + F623A66C2635B57500F50371 /* NumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A66B2635B57500F50371 /* NumberFormatter.swift */; }; + F623A6742635B5BE00F50371 /* Enum+Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A6732635B5BE00F50371 /* Enum+Extended.swift */; }; + F623A67B2635B5F900F50371 /* Date+Styled.swift in Sources */ = {isa = PBXBuildFile; fileRef = F623A67A2635B5F900F50371 /* Date+Styled.swift */; }; F62B93A7261A492700D7F8E6 /* String+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = F62B93A6261A492700D7F8E6 /* String+Size.swift */; }; F68C2D422616482A00042967 /* IsoDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68C2D412616482A00042967 /* IsoDateFormatter.swift */; }; F6A251A0260B670000132DEC /* AppleLibs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A25196260B66FF00132DEC /* AppleLibs.framework */; }; @@ -27,6 +34,13 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + F623A64C2635B2B100F50371 /* Array+Extended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extended.swift"; sourceTree = "<group>"; }; + F623A6552635B34100F50371 /* Sequence+Extended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Extended.swift"; sourceTree = "<group>"; }; + F623A65D2635B38200F50371 /* CharacterSet+Url.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CharacterSet+Url.swift"; sourceTree = "<group>"; }; + F623A6642635B3A800F50371 /* Dictornary+Url.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictornary+Url.swift"; sourceTree = "<group>"; }; + F623A66B2635B57500F50371 /* NumberFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberFormatter.swift; sourceTree = "<group>"; }; + F623A6732635B5BE00F50371 /* Enum+Extended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Enum+Extended.swift"; sourceTree = "<group>"; }; + F623A67A2635B5F900F50371 /* Date+Styled.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Styled.swift"; sourceTree = "<group>"; }; F62B93A6261A492700D7F8E6 /* String+Size.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Size.swift"; sourceTree = "<group>"; }; F68C2D412616482A00042967 /* IsoDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsoDateFormatter.swift; sourceTree = "<group>"; }; F6A25196260B66FF00132DEC /* AppleLibs.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppleLibs.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -59,6 +73,25 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F623A6532635B32900F50371 /* Collections */ = { + isa = PBXGroup; + children = ( + F623A64C2635B2B100F50371 /* Array+Extended.swift */, + F623A6552635B34100F50371 /* Sequence+Extended.swift */, + F623A6732635B5BE00F50371 /* Enum+Extended.swift */, + ); + path = Collections; + sourceTree = "<group>"; + }; + F623A65C2635B36900F50371 /* Network */ = { + isa = PBXGroup; + children = ( + F623A65D2635B38200F50371 /* CharacterSet+Url.swift */, + F623A6642635B3A800F50371 /* Dictornary+Url.swift */, + ); + path = Network; + sourceTree = "<group>"; + }; F62B93A5261A491100D7F8E6 /* String */ = { isa = PBXGroup; children = ( @@ -72,6 +105,7 @@ isa = PBXGroup; children = ( F68C2D412616482A00042967 /* IsoDateFormatter.swift */, + F623A67A2635B5F900F50371 /* Date+Styled.swift */, ); path = Date; sourceTree = "<group>"; @@ -98,6 +132,8 @@ F6A25198260B66FF00132DEC /* AppleLibs */ = { isa = PBXGroup; children = ( + F623A65C2635B36900F50371 /* Network */, + F623A6532635B32900F50371 /* Collections */, F62B93A5261A491100D7F8E6 /* String */, F68C2D402616482000042967 /* Date */, F6A251B8260B696200132DEC /* Numbers */, @@ -120,6 +156,7 @@ isa = PBXGroup; children = ( F6A251B9260B697300132DEC /* Double+Rounded.swift */, + F623A66B2635B57500F50371 /* NumberFormatter.swift */, ); path = Numbers; sourceTree = "<group>"; @@ -233,10 +270,17 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F623A65E2635B38200F50371 /* CharacterSet+Url.swift in Sources */, F6A251BA260B697300132DEC /* Double+Rounded.swift in Sources */, + F623A64D2635B2B100F50371 /* Array+Extended.swift in Sources */, F62B93A7261A492700D7F8E6 /* String+Size.swift in Sources */, + F623A67B2635B5F900F50371 /* Date+Styled.swift in Sources */, + F623A6652635B3A800F50371 /* Dictornary+Url.swift in Sources */, + F623A6562635B34100F50371 /* Sequence+Extended.swift in Sources */, F68C2D422616482A00042967 /* IsoDateFormatter.swift in Sources */, + F623A66C2635B57500F50371 /* NumberFormatter.swift in Sources */, F6A251BE260B699100132DEC /* String+Html.swift in Sources */, + F623A6742635B5BE00F50371 /* Enum+Extended.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AppleLibs/Collections/Array+Extended.swift b/AppleLibs/Collections/Array+Extended.swift new file mode 100644 index 0000000000000000000000000000000000000000..e7ba6966211deab712f67fab12bee43737abcb87 --- /dev/null +++ b/AppleLibs/Collections/Array+Extended.swift @@ -0,0 +1,24 @@ +// +// Array+Extended.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension Array where Element: Equatable +{ + func containSameElements(_ array: [Element]) -> Bool { + var selfCopy = self + var secondArrayCopy = array + while let currentItem = selfCopy.popLast() { + if let indexOfCurrentItem = secondArrayCopy.firstIndex(of: currentItem) { + secondArrayCopy.remove(at: indexOfCurrentItem) + } else { + return false + } + } + return secondArrayCopy.isEmpty + } +} diff --git a/AppleLibs/Collections/Enum+Extended.swift b/AppleLibs/Collections/Enum+Extended.swift new file mode 100644 index 0000000000000000000000000000000000000000..5c644d965d2e376bdecd6a90481e549018228f24 --- /dev/null +++ b/AppleLibs/Collections/Enum+Extended.swift @@ -0,0 +1,15 @@ +// +// Enum+Extended.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension CaseIterable where Self: RawRepresentable, Self.RawValue == String +{ + static var allStrings: [String] { + Self.allCases.map({ $0.rawValue }) + } +} diff --git a/AppleLibs/Collections/Sequence+Extended.swift b/AppleLibs/Collections/Sequence+Extended.swift new file mode 100644 index 0000000000000000000000000000000000000000..a2a12d085ec684c2eaa504fffda0032b408c307e --- /dev/null +++ b/AppleLibs/Collections/Sequence+Extended.swift @@ -0,0 +1,18 @@ +// +// Sequence+Extended.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension Sequence where Iterator.Element: Hashable +{ + var distinct: [Iterator.Element] { + var seen: [Iterator.Element: Bool] = [:] + return self.filter { + seen.updateValue(true, forKey: $0) == nil + } + } +} diff --git a/AppleLibs/Date/Date+Styled.swift b/AppleLibs/Date/Date+Styled.swift new file mode 100644 index 0000000000000000000000000000000000000000..70299e3aedf23b2b5942800a28a8e49aea62e59f --- /dev/null +++ b/AppleLibs/Date/Date+Styled.swift @@ -0,0 +1,36 @@ +// +// Date+Styled.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension Date +{ + enum DateStyle: String + { + case ddmmyyyy = "dd.MM.yyyy" + case ddmmyyyyHHmm = "dd.MM.yyyy HH:mm" + case HHmm = "HH:mm" + } + + func styled(style: DateStyle) -> String { + return styled(style: style.rawValue) + } + + func styled(style: String) -> String { + let dateFormatter: DateFormatter = DateFormatter() + dateFormatter.dateFormat = style + return dateFormatter.string(from: self) + } + + func combineWithTime(time: Date?) -> Date? { + if let time = time { + let timeComponents = Calendar.current.dateComponents([.hour, .minute], from: time) + return Calendar.current.date(bySettingHour: timeComponents.hour ?? 0, minute: timeComponents.minute ?? 0, second: timeComponents.second ?? 0, of: self) + } + return nil + } +} diff --git a/AppleLibs/Network/CharacterSet+Url.swift b/AppleLibs/Network/CharacterSet+Url.swift new file mode 100644 index 0000000000000000000000000000000000000000..de7e984d495043af6dcd02382d89d420c4f40687 --- /dev/null +++ b/AppleLibs/Network/CharacterSet+Url.swift @@ -0,0 +1,20 @@ +// +// CharacterSet+Url.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension CharacterSet +{ + static let urlQueryValueAllowed: CharacterSet = { + let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 + let subDelimitersToEncode = "!$&'()*+,;=" + + var allowed = CharacterSet.urlQueryAllowed + allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") + return allowed + }() +} diff --git a/AppleLibs/Network/Dictornary+Url.swift b/AppleLibs/Network/Dictornary+Url.swift new file mode 100644 index 0000000000000000000000000000000000000000..642f6903575bf510bdefe7d5eaac334268135922 --- /dev/null +++ b/AppleLibs/Network/Dictornary+Url.swift @@ -0,0 +1,21 @@ +// +// Dictornary+Url.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension Dictionary +{ + func percentEncoded() -> Data? { + return map { key, value in + let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? "" + let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? "" + return escapedKey + "=" + escapedValue + } + .joined(separator: "&") + .data(using: .utf8) + } +} diff --git a/AppleLibs/Numbers/NumberFormatter.swift b/AppleLibs/Numbers/NumberFormatter.swift new file mode 100644 index 0000000000000000000000000000000000000000..052f176a55b83f164721011bb42a10acc67f75e2 --- /dev/null +++ b/AppleLibs/Numbers/NumberFormatter.swift @@ -0,0 +1,51 @@ +// +// NumberFormatter.swift +// AppleLibs +// +// Created by Tobias on 25.04.21. +// + +import Foundation + +public extension Int +{ + var styled: String { + let formatter = NumberFormatter() + formatter.numberStyle = .none + return formatter.string(from: NSNumber(value: self)) ?? "" + } + + static func parse(input: String) -> Int? { + Int(input) + } +} + +public extension Int64 +{ + var styled: String { + let formatter = NumberFormatter() + formatter.numberStyle = .none + return formatter.string(from: NSNumber(value: self)) ?? "" + } + + static func parse(input: String) -> Int64? { + Int64(input) + } +} + +public extension Double +{ + var styled: String { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.usesGroupingSeparator = false + formatter.groupingSeparator = "" + return formatter.string(from: NSNumber(value: self)) ?? "" + } + + static func parse(input: String) -> Double? { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + return formatter.number(from: input)?.doubleValue + } +}