// // String+Extension.swift // Nextcloud // // Created by Marino Faggiana on 22/12/20. // Copyright © 2020 Marino Faggiana. All rights reserved. // // Author Marino Faggiana // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // import Foundation import UIKit import CryptoKit extension String { var alphanumeric: String { return self.components(separatedBy: CharacterSet.alphanumerics.inverted).joined().lowercased() } var isNumber: Bool { return self.allSatisfy { character in character.isNumber } } public var uppercaseInitials: String? { let initials = self.components(separatedBy: .whitespaces) .reduce("", { guard $0.count < 2, let nextLetter = $1.first else { return $0 } return $0 + nextLetter.uppercased() }) return initials.isEmpty ? nil : initials } func formatSecondsToString(_ seconds: TimeInterval) -> String { if seconds.isNaN { return "00:00:00" } let sec = Int(seconds.truncatingRemainder(dividingBy: 60)) let min = Int(seconds.truncatingRemainder(dividingBy: 3600) / 60) let hour = Int(seconds / 3600) return String(format: "%02d:%02d:%02d", hour, min, sec) } func md5() -> String { let digest = Insecure.MD5.hash(data: self.data(using: .utf8) ?? Data()) return digest.map { String(format: "%02hhx", $0) }.joined() } /* DEPRECATED iOS 13 func md5() -> String { // https://stackoverflow.com/a/32166735/9506784 let length = Int(CC_MD5_DIGEST_LENGTH) let messageData = self.data(using: .utf8) ?? Data() var digestData = Data(count: length) _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in messageData.withUnsafeBytes { messageBytes -> UInt8 in if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress { let messageLength = CC_LONG(messageData.count) CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory) } return 0 } } return digestData.map { String(format: "%02hhx", $0) }.joined() } */ var urlEncoded: String? { // + for historical reason, most web servers treat + as a replacement of whitespace // ?, & mark query pararmeter which should not be part of a url string, but added seperately let urlAllowedCharSet = CharacterSet.urlQueryAllowed.subtracting(["+", "?", "&"]) return addingPercentEncoding(withAllowedCharacters: urlAllowedCharSet) } } extension StringProtocol { var firstUppercased: String { lowercased().prefix(1).uppercased() + dropFirst() } }