added iOS source code
[wl-app.git] / iOS / WolneLektury / Extensions / String+Ext.swift
1 //
2 //  String+Ext.swift
3 //  WolneLektury
4 //
5 //  Created by Pawel Dabrowski on 30/05/2018.
6 //  Copyright © 2018 Fundacja Nowoczesna Polska. All rights reserved.
7 //
8
9 import Foundation
10
11 import UIKit
12
13 extension String{
14     
15     var trimmed: String {
16         return trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
17     }
18     
19     var trimmedLength: Int{
20         get {
21             return trimmed.count
22         }
23     }
24     
25     var isBlank: Bool {
26         get {
27             return trimmedLength == 0
28         }
29     }
30     
31     //Validate Email
32     var isEmail: Bool {
33         do {
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
37         } catch {
38             return false
39         }
40     }
41     
42     var isPostCode: Bool{
43         
44         let pinRegex =  "^\\d{2}-\\d{3}$" //"^[0-9]{6}$"
45         let predicate = NSPredicate(format: "SELF MATCHES %@", pinRegex)
46         
47         let result =  predicate.evaluate(with:self)
48         return result
49     }
50     
51     var localized: String {
52         return NSLocalizedString(self, comment: "")
53     }
54     
55     func base64Encoded() -> String? {
56         if let data = self.data(using: .utf8) {
57             return data.base64EncodedString()
58         }
59         return nil
60     }
61     
62     func base64Decoded() -> String? {
63         if let data = Data(base64Encoded: self) {
64             return String(data: data, encoding: .utf8)
65         }
66         return nil
67     }
68     
69     var numericOnly: Bool{
70         get{
71             return CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: self))
72         }
73     }
74     
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)
78         
79         return ceil(boundingBox.height)
80     }
81     
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)
85         
86         return ceil(boundingBox.width)
87     }
88     
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])
93     }
94     
95     func getUrl() -> URL? {
96         if let escapedUrl = self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: escapedUrl){
97             return url
98         }
99         return nil
100     }
101     
102     func utf8DecodedString()-> String {
103         let data = self.data(using: .utf8)
104         if let message = String(data: data!, encoding: .nonLossyASCII){
105             return message
106         }
107         return ""
108     }
109     
110     func utf8EncodedString()-> String {
111         let messageData = self.data(using: .nonLossyASCII)
112         let text = String(data: messageData!, encoding: .utf8)
113         return text!
114     }
115     
116     //
117     //  from oauhSwift
118     //
119     
120     func urlEncoded() -> String {
121         let customAllowedSet = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")
122         return self.addingPercentEncoding(withAllowedCharacters: customAllowedSet)!
123     }
124     
125     var parametersFromQueryString: [String: String] {
126         return dictionaryBySplitting("&", keyValueSeparator: "=")
127     }
128     
129     var urlQueryEncoded: String? {
130         return self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
131     }
132     
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? {
135         if value.isEmpty {
136             return self
137         } else if let value = encode ? value.urlQueryEncoded : value {
138             return "\(self)\(self.isEmpty ? "" : "&")\(name)=\(value)"
139         } else {
140             encodeError?(name, value)
141             return nil
142         }
143     }
144     
145     /// Returns new url string by appending query string at the end.
146     func urlByAppending(query: String) -> String {
147         return "\(self)\(self.contains("?") ? "&" : "?")\(query)"
148     }
149     
150     fileprivate func dictionaryBySplitting(_ elementSeparator: String, keyValueSeparator: String) -> [String: String] {
151         var string = self
152         
153         if hasPrefix(elementSeparator) {
154             string = String(dropFirst(1))
155         }
156         
157         var parameters = [String: String]()
158         
159         let scanner = Scanner(string: string)
160         
161         var key: NSString?
162         var value: NSString?
163         
164         while !scanner.isAtEnd {
165             key = nil
166             scanner.scanUpTo(keyValueSeparator, into: &key)
167             scanner.scanString(keyValueSeparator, into: nil)
168             
169             value = nil
170             scanner.scanUpTo(elementSeparator, into: &value)
171             scanner.scanString(elementSeparator, into: nil)
172             
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))
179                         }
180                         for flag in keys {
181                             parameters.updateValue("", forKey: flag)
182                         }
183                     } else {
184                         parameters.updateValue(value, forKey: key)
185                     }
186                 } else {
187                     parameters.updateValue("", forKey: key)
188                 }
189             }
190         }
191         
192         return parameters
193     }
194
195     func getPhotoUrl() -> URL?{
196         
197         if self.count > 0{
198             var str = self
199             
200             if (!self.contains(Config.MEDIA_URL) && !self.contains(Config.MEDIA_URL_HTTPS)) {
201                 str = Config.MEDIA_URL + str
202             }
203             return str.getUrl()
204         }
205         return nil
206     }
207     
208     func sizeOf(_ font: UIFont) -> CGSize {
209         return self.size(withAttributes: [NSAttributedStringKey.font: font])
210     }
211 }