5 // Created by Pawel Dabrowski on 30/05/2018.
6 // Copyright © 2018 Fundacja Nowoczesna Polska. All rights reserved.
16 return trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
19 var trimmedLength: Int{
27 return trimmedLength == 0
34 let regex = try NSRegularExpression(pattern: "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", options: .caseInsensitive)
35 let selfTrimmed = self.trimmed
36 return regex.firstMatch(in: selfTrimmed, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, selfTrimmed.characters.count)) != nil
44 let pinRegex = "^\\d{2}-\\d{3}$" //"^[0-9]{6}$"
45 let predicate = NSPredicate(format: "SELF MATCHES %@", pinRegex)
47 let result = predicate.evaluate(with:self)
51 var localized: String {
52 return NSLocalizedString(self, comment: "")
55 func base64Encoded() -> String? {
56 if let data = self.data(using: .utf8) {
57 return data.base64EncodedString()
62 func base64Decoded() -> String? {
63 if let data = Data(base64Encoded: self) {
64 return String(data: data, encoding: .utf8)
69 var numericOnly: Bool{
71 return CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: self))
75 func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
76 let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
77 let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)
79 return ceil(boundingBox.height)
82 func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
83 let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
84 let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)
86 return ceil(boundingBox.width)
89 subscript(_ range: CountableRange<Int>) -> String {
90 let idx1 = index(startIndex, offsetBy: range.lowerBound)
91 let idx2 = index(startIndex, offsetBy: range.upperBound)
92 return String(self[idx1..<idx2])
95 func getUrl() -> URL? {
96 if let escapedUrl = self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: escapedUrl){
102 func utf8DecodedString()-> String {
103 let data = self.data(using: .utf8)
104 if let message = String(data: data!, encoding: .nonLossyASCII){
110 func utf8EncodedString()-> String {
111 let messageData = self.data(using: .nonLossyASCII)
112 let text = String(data: messageData!, encoding: .utf8)
120 func urlEncoded() -> String {
121 let customAllowedSet = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")
122 return self.addingPercentEncoding(withAllowedCharacters: customAllowedSet)!
125 var parametersFromQueryString: [String: String] {
126 return dictionaryBySplitting("&", keyValueSeparator: "=")
129 var urlQueryEncoded: String? {
130 return self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
133 /// Returns new url query string by appending query parameter encoding it first, if specified.
134 func urlQueryByAppending(parameter name: String, value: String, encode: Bool = true, _ encodeError: ((String, String) -> Void)? = nil) -> String? {
137 } else if let value = encode ? value.urlQueryEncoded : value {
138 return "\(self)\(self.isEmpty ? "" : "&")\(name)=\(value)"
140 encodeError?(name, value)
145 /// Returns new url string by appending query string at the end.
146 func urlByAppending(query: String) -> String {
147 return "\(self)\(self.contains("?") ? "&" : "?")\(query)"
150 fileprivate func dictionaryBySplitting(_ elementSeparator: String, keyValueSeparator: String) -> [String: String] {
153 if hasPrefix(elementSeparator) {
154 string = String(dropFirst(1))
157 var parameters = [String: String]()
159 let scanner = Scanner(string: string)
164 while !scanner.isAtEnd {
166 scanner.scanUpTo(keyValueSeparator, into: &key)
167 scanner.scanString(keyValueSeparator, into: nil)
170 scanner.scanUpTo(elementSeparator, into: &value)
171 scanner.scanString(elementSeparator, into: nil)
173 if let key = key as String? {
174 if let value = value as String? {
175 if key.contains(elementSeparator) {
176 var keys = key.components(separatedBy: elementSeparator)
177 if let key = keys.popLast() {
178 parameters.updateValue(value, forKey: String(key))
181 parameters.updateValue("", forKey: flag)
184 parameters.updateValue(value, forKey: key)
187 parameters.updateValue("", forKey: key)
195 func getPhotoUrl() -> URL?{
200 if (!self.contains(Config.MEDIA_URL) && !self.contains(Config.MEDIA_URL_HTTPS)) {
201 str = Config.MEDIA_URL + str
208 func sizeOf(_ font: UIFont) -> CGSize {
209 return self.size(withAttributes: [NSAttributedStringKey.font: font])