diff --git a/AppleLibs.xcodeproj/project.pbxproj b/AppleLibs.xcodeproj/project.pbxproj index 7211c1bae4e519e0f98c93a16e832e9ec769d49e..258563d0b555034ce78d802cc22a8143dcbb37a1 100644 --- a/AppleLibs.xcodeproj/project.pbxproj +++ b/AppleLibs.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ F673A9A12635EF8D0017AD37 /* Future in Frameworks */ = {isa = PBXBuildFile; productRef = F673A9A02635EF8D0017AD37 /* Future */; }; F68BFE6B263B28B000E893E5 /* UIViewController+Screenshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68BFE6A263B28B000E893E5 /* UIViewController+Screenshot.swift */; }; F68C2D422616482A00042967 /* IsoDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68C2D412616482A00042967 /* IsoDateFormatter.swift */; }; + F6991D0A275AC34200C5AFFD /* TemplatedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6991D09275AC34200C5AFFD /* TemplatedString.swift */; }; F6A251A0260B670000132DEC /* AppleLibs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A25196260B66FF00132DEC /* AppleLibs.framework */; }; F6A251A5260B670000132DEC /* AppleLibsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A251A4260B670000132DEC /* AppleLibsTests.swift */; }; F6A251A7260B670000132DEC /* AppleLibs.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A25199260B66FF00132DEC /* AppleLibs.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -61,6 +62,7 @@ F673A9932635EF510017AD37 /* RequestBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestBuilder.swift; sourceTree = "<group>"; }; F68BFE6A263B28B000E893E5 /* UIViewController+Screenshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Screenshot.swift"; sourceTree = "<group>"; }; F68C2D412616482A00042967 /* IsoDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsoDateFormatter.swift; sourceTree = "<group>"; }; + F6991D09275AC34200C5AFFD /* TemplatedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatedString.swift; sourceTree = "<group>"; }; F6A25196260B66FF00132DEC /* AppleLibs.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppleLibs.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F6A25199260B66FF00132DEC /* AppleLibs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleLibs.h; sourceTree = "<group>"; }; F6A2519A260B66FF00132DEC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; @@ -129,6 +131,7 @@ children = ( F6A251BD260B699100132DEC /* String+Html.swift */, F62B93A6261A492700D7F8E6 /* String+Size.swift */, + F6991D09275AC34200C5AFFD /* TemplatedString.swift */, ); path = String; sourceTree = "<group>"; @@ -343,6 +346,7 @@ F623A66C2635B57500F50371 /* NumberFormatter.swift in Sources */, F6CD575026D246470051B38E /* Float+Rounded.swift in Sources */, F6A251BE260B699100132DEC /* String+Html.swift in Sources */, + F6991D0A275AC34200C5AFFD /* TemplatedString.swift in Sources */, F673A9952635EF510017AD37 /* HttpStatusCode.swift in Sources */, F6450F6D26A0CEA200076347 /* UIColor+Hex.swift in Sources */, F673A9982635EF510017AD37 /* ResponseHandler.swift in Sources */, diff --git a/AppleLibs/Utils/String/TemplatedString.swift b/AppleLibs/Utils/String/TemplatedString.swift new file mode 100644 index 0000000000000000000000000000000000000000..04b1399be63d5c30975cb1563c9d702727e0a73f --- /dev/null +++ b/AppleLibs/Utils/String/TemplatedString.swift @@ -0,0 +1,48 @@ +// +// TemplatedString.swift +// AppleLibs +// +// Created by Tobias on 03.12.21. +// +// Source: https://medium.com/flawless-app-stories/minimal-templating-system-in-swift-in-only-10-lines-b031963150e7 +// + +import Foundation + +@dynamicMemberLookup +struct TemplatedString +{ + var template : String + private var data : [String:String] + var evaluatedString : String { data.reduce(template) { $0.replacingOccurrences(of: "${#\($1.key)}", with: $1.value) } } + + init(template: String, data: [String:String] = [:]) { + self.template = template + self.data = data + } + + subscript (dynamicMember member: String) -> CustomStringConvertible? { + get { + data[member] + } + set { + data[member] = newValue?.description + } + } + + subscript (dynamicMember member: String) -> Date { + get { + dateFormatter.date(from: data[member] ?? "") ?? Date(timeIntervalSince1970: 0) + } + set { + data[member] = dateFormatter.string(from: newValue) + } + } + + let dateFormatter : DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" + formatter.calendar = Calendar(identifier: .gregorian) + return formatter + }() +}