jsdw_ios/QuickLocation/Core/Extension/String+Extension.swift

515 lines
16 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// String+public extension.swift
// SwiftBasics
//
// Created by on 17/1/11.
// Copyright © 2017 . All rights reserved.
//
import Foundation
import SwiftyJSON
import CommonCrypto
import URLNavigator
public extension String {
var completePicUrl: String {
if !self.hasPrefix("http") {
if self.hasPrefix("//") {
return "http:" + self
} else {
return "http://fec-img.gan-hai.com" + self
}
} else {
return self
}
}
var length: Int { return self.count }
}
public extension JSON {
/// JSON to String
var jsonString: String { return rawString(String.Encoding.utf8, options: JSONSerialization.WritingOptions()) ?? "" }
}
// MARK: URL encode/decode
public extension String {
/// URL
var urlEncoded: String {
return self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed) ?? self
}
var urlEncodingWithQueryAllowedCharacters: String {
return self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? self
}
/// URL
var urlDecoded: String {
return self.removingPercentEncoding ?? self
}
}
// MARK: md5
public extension String {
var MD5String: String {
let cStrl = cString(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue));
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 16);
CC_MD5(cStrl, CC_LONG(strlen(cStrl!)), buffer);
var md5String = "";
for idx in 0...15 {
let obcStrl = String.init(format: "%02x", buffer[idx]);
md5String.append(obcStrl);
}
free(buffer);
return md5String;
}
}
// MARK: Base64
public extension String {
/// Base64
var base64Encoded: String {
return data.base64EncodedString(options: [])
}
/// Base64
var base64Decoded: String {
return Data(base64Encoded: self, options: [])?.string ?? ""
}
}
public extension String {
var md5: String {
let data = self.data
var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
CC_MD5((data as NSData).bytes, CC_LONG(data.count), &digest)
let hexBytes = digest.map { String(format: "%02hhx", $0) }
return hexBytes.joined(separator: "")
}
var sha1: String {
let data = self.data
var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
CC_SHA1((data as NSData).bytes, CC_LONG(data.count), &digest)
let hexBytes = digest.map { String(format: "%02hhx", $0) }
return hexBytes.joined(separator: "")
}
}
// MARK: Get the size of the text
public extension String {
///
func size(fontSize: CGFloat, width: CGFloat = CGFloat.greatestFiniteMagnitude) -> CGSize {
return size(font: UIFont.systemFont(ofSize: fontSize), width: width)
}
///
func size(font: UIFont, width: CGFloat = CGFloat.greatestFiniteMagnitude) -> CGSize {
let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byWordWrapping
let attributes = [
NSAttributedString.Key.font: font,
NSAttributedString.Key.paragraphStyle: paragraphStyle.copy()
]
return (self as NSString).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil).size
}
///
/// - Parameter count:
/// - Returns:
func lineHeight(_ count: Int = 1,
font: UIFont,
width: CGFloat = CGFloat.greatestFiniteMagnitude) -> CGFloat {
size(font: font, width: width).height * CGFloat(count)
}
}
// MARK: Substring
public extension String {
func substring(_ fromIndex: Int, _ toIndex: Int = Int.max) -> String? {
let len = self.length
var start: Int
var end: Int
if fromIndex < 0 {
start = 0
end = len + fromIndex
} else {
start = fromIndex
if toIndex < 0 {
end = len + toIndex
} else {
end = min(toIndex, len)
}
}
if start > end {
return nil
}
return self[start..<end]
}
subscript(range: Range<Int>) -> String? {
let len = self.length
if range.lowerBound >= len || range.upperBound < 0 {
return nil
}
let startIndex = self.index(self.startIndex, offsetBy: max(0, range.lowerBound))
let endIndex = self.index(self.startIndex, offsetBy: min(len, range.upperBound))
return String(self[startIndex..<endIndex])
}
subscript(index: Int) -> Character? {
if index < 0 || index >= self.length {
return nil
}
return self[self.index(self.startIndex, offsetBy: index)]
}
}
// MARK: Trim
public extension String {
/// Tab
var trimmed: String {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}
// MARK: Localized String
public extension String {
var localizedString: String {
return NSLocalizedString(self, comment: "")
}
}
// MARK: - NSData
public extension String {
/// UTF8NSData
var data: Data {
return self.data(using: String.Encoding.utf8, allowLossyConversion: false)!
}
}
public extension Data {
/// UTF8
var string: String {
return String(data: self, encoding: String.Encoding.utf8) ?? ""
}
}
// MARK: - Int
public extension String {
var int: Int32 { return (self as NSString).intValue }
var integer: Int { return (self as NSString).integerValue }
}
public extension Int {
var string: String { return String(self) }
}
// MARK: - Float
public extension String {
var float: Float { return (self as NSString).floatValue }
}
public extension Float {
var string: String { return String(self) }
}
// MARK: - Double
public extension String {
var double: Double { return (self as NSString).doubleValue }
}
public extension Double {
var string: String { return String(self) }
}
// MARK: - Bool
public extension String {
var bool: Bool { return (self as NSString).boolValue }
}
public extension Bool {
var string: String { return self ? "true" : "false" }
}
public extension String {
//
func getFileSize() -> UInt64 {
var size: UInt64 = 0
let fileManager = FileManager.default
var isDir: ObjCBool = false
let isExists = fileManager.fileExists(atPath: self, isDirectory: &isDir)
//
if isExists {
//
if isDir.boolValue {
//
let enumerator = fileManager.enumerator(atPath: self)
for subPath in enumerator! {
//
let fullPath = self.appending("/\(subPath)")
do {
let attr = try fileManager.attributesOfItem(atPath: fullPath)
size += attr[FileAttributeKey.size] as! UInt64
} catch {
print("error :\(error)")
}
}
} else { //
do {
let attr = try fileManager.attributesOfItem(atPath: self)
size += attr[FileAttributeKey.size] as! UInt64
} catch {
print("error :\(error)")
}
}
}
return size
}
}
// MARK: -
public extension String {
func changeTextColor(color: UIColor, font: UIFont, text: String) -> NSMutableAttributedString {
let nsString = NSString(string: self)
let attributeString = NSMutableAttributedString(string: self)
let arrRange = rangeOfString(string: nsString, andInString: text)
for range in arrRange {
attributeString.addAttributes([NSAttributedString.Key.font: font], range: range)
attributeString.addAttributes([NSAttributedString.Key.foregroundColor: color], range: range)
}
return attributeString
}
func changeTextColor(color: UIColor, font: UIFont, firstText: String, secondText: String) -> NSMutableAttributedString {
let nsString = NSString(string: self)
let attributeString = NSMutableAttributedString(string: self)
let firstArrRange = rangeOfString(string: nsString, andInString: firstText)
for range in firstArrRange {
attributeString.addAttributes([NSAttributedString.Key.font: font], range: range)
attributeString.addAttributes([NSAttributedString.Key.foregroundColor: color], range: range)
}
let secondArrRange = rangeOfString(string: nsString, andInString: secondText)
for range in secondArrRange {
attributeString.addAttributes([NSAttributedString.Key.font: font], range: range)
attributeString.addAttributes([NSAttributedString.Key.foregroundColor: color], range: range)
}
return attributeString
}
/// ()
/// - Parameter string:
/// - Parameter inString:
private func rangeOfString(string:NSString,
andInString inString:String) -> [NSRange] {
var arrRange = [NSRange]()
var _fullText = string
var rang:NSRange = _fullText.range(of: inString)
while rang.location != NSNotFound {
var location:Int = 0
if arrRange.count > 0 {
if arrRange.last!.location + arrRange.last!.length < string.length {
location = arrRange.last!.location + arrRange.last!.length
}
}
_fullText = NSString.init(string: _fullText.substring(from: rang.location + rang.length))
if arrRange.count > 0 {
rang.location += location
}
arrRange.append(rang)
rang = _fullText.range(of: inString)
}
return arrRange
}
}
public extension String {
/// URL
var urlQueryParameters: [String: String] {
guard let url = URL(string: self) else { return [:] }
return url.queryParameters
}
/// String
var urlParameters: [String: AnyObject]? {
//
let text = self as NSString
let range = text.range(of: "?")
var params = [String: AnyObject]()
//
let paramsString = text.substring(with: range)
//
if paramsString.contains("&") {
//
let urlComponents = paramsString.components(separatedBy: "&")
//
for keyValuePair in urlComponents {
// Key/Value
let pairComponents = keyValuePair.components(separatedBy: "=")
let key = pairComponents.first?.removingPercentEncoding
let value = pairComponents.last?.removingPercentEncoding
//
if let key = key, let value = value {
params[key] = value as AnyObject
//
// if let existValue = params[key] {
// if var existValue = existValue as? [AnyObject] {
// existValue.append(value)
// } else {
// params[key] = [existValue, value]
// }
// } else {
// params[key] = value as AnyObject
// }
}
}
} else {
//
let pairComponents = paramsString.components(separatedBy: "=")
//
if pairComponents.count == 1 {
return nil
}
let key = pairComponents.first?.removingPercentEncoding
let value = pairComponents.last?.removingPercentEncoding
if let key = key, let value = value {
params[key] = value as AnyObject
}
}
return params
}
}
public extension String {
func custemReplaceString(of targetStr:String,
with replaceStr:String,
replaceColor: UIColor) -> NSMutableAttributedString {
let labelString = self.replacingOccurrences(of: targetStr, with: replaceStr)
let nsString = labelString as NSString
let range = nsString.range(of: replaceStr)
let mutableStr = NSMutableAttributedString(string: labelString)
mutableStr.setAttributes([NSAttributedString.Key.foregroundColor: replaceColor], range: range)
return mutableStr
}
}
public extension String {
/// 0
var phoneFromatter: String {
if let phone = Int64(self) {
return String(phone)
}
return self
}
}
// MARK: - NSNumber
public extension String {
var number: NSNumber? {
let boolNumbers = ["true": true, "false": false, "yes": true, "no": false]
let nilNumbers = ["nil", "null", "(null)", "<null>"]
let lowerStr = self.lowercased()
if let value = boolNumbers[lowerStr] { return NSNumber(value: value) }
if nilNumbers.contains(lowerStr) { return nil }
guard let cstring = self.cString(using: .utf8) else { return nil }
if self.rangeOfCharacter(from: CharacterSet(charactersIn: ".")) != nil {
let cnumber = atof(cstring)
if cnumber.isNaN || cnumber.isInfinite { return nil }
return NSNumber(value: cnumber)
} else {
return NSNumber(value: atoll(cstring))
}
}
}
// MARK: -
public extension String {
/// Email
static func checkEmailAddressIsValid(address: String?) -> Bool {
guard address != nil else {
return false
}
let regular = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
let regularEmail = NSPredicate(format: "SELF MATCHES %@", regular)
return regularEmail.evaluate(with: address)
}
}
// MARK: - ****
extension String {
///
func phoneFormat() -> String {
guard self.length > 6 else { return self }
let preStr = self.substring(0, 3)
let suffixStr = self.substring(self.length - 4, self.length)
return (preStr ?? "") + "****" + (suffixStr ?? "")
}
}
// MARK: -
extension String {
func createQRCode(size: CGSize = CGSize(width: 200, height: 200)) -> UIImage? {
// 1. Data
guard let data = self.data(using: .utf8) else { return nil }
// 2.
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
qrFilter.setDefaults()
qrFilter.setValue(data, forKey: "inputMessage")
// L(7%)/M(15%)/Q(25%)/H(30%)
qrFilter.setValue("H", forKey: "inputCorrectionLevel")
// 3. CIImage
guard let ciImage = qrFilter.outputImage else { return nil }
let scaleX = size.width / ciImage.extent.width
let scaleY = size.height / ciImage.extent.height
let transform = CGAffineTransform(scaleX: scaleX, y: scaleY)
let scaledCI = ciImage.transformed(by: transform)
// 4. UIImage
if let cgImage = CIContext(options: [.useSoftwareRenderer: false]).createCGImage(scaledCI, from: scaledCI.extent) {
return UIImage(cgImage: cgImage)
}
return nil
}
}