Skip to content
This repository has been archived by the owner on Mar 30, 2021. It is now read-only.

Commit

Permalink
Merge pull request #23 from 4alltecnologia/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
lucaschifino authored Aug 22, 2019
2 parents 9a14a2b + cd3efca commit fddf820
Show file tree
Hide file tree
Showing 25 changed files with 959 additions and 67 deletions.
2 changes: 1 addition & 1 deletion 4allUtilitiesCore.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#

s.name = "4allUtilitiesCore"
s.version = "0.1.0"
s.version = "0.3.0"
s.summary = "A utilities core library."

# This description is used to generate tags and improve search results.
Expand Down
130 changes: 107 additions & 23 deletions UtilitiesCore.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions UtilitiesCore/Extensions/Date+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Date+Extension.swift
// UtilitiesCore
//
// Created by Luca Saldanha Schifino on 07/08/19.
// Copyright © 2019 4all. All rights reserved.
//

import Foundation

public extension Date {

/// String describing elapsed time from date to now.
var brazilianElapsedInterval: String {
let interval = Calendar.current.dateComponents([.year, .month, .day, .hour], from: self, to: Date())

if let year = interval.year, year > 0 {
return year == 1 ? "\(year)" + " " + "ano" :
"\(year)" + " " + "anos"
} else if let month = interval.month, month > 0 {
return month == 1 ? "\(month)" + " " + "mês" :
"\(month)" + " " + "meses"
} else if let day = interval.day, day > 0 {
return day == 1 ? "\(day)" + " " + "dia" :
"\(day)" + " " + "dias"
} else if let hour = interval.hour, hour > 0 {
return hour == 1 ? "\(hour)" + " " + "hora" :
"\(hour)" + " " + "horas"
} else {
return "agora"
}
}

/// Returns String from date.
///
/// - Parameters:
/// - format: Date format.
/// - timezone: TimeZone for the date. If none is passed, the device's locale is used.
/// - Returns: Date's String.
func getString(withFormat format: String, andTimezoneAbbreviation abbreviation: String? = nil) -> String {
let dateFormatter = DateFormatter()
if let abbreviation = abbreviation {
dateFormatter.timeZone = TimeZone(abbreviation: abbreviation)
}
dateFormatter.dateFormat = format
return dateFormatter.string(from: self)
}
}
17 changes: 17 additions & 0 deletions UtilitiesCore/Extensions/Float+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Float+Extension.swift
// UtilitiesCore
//
// Created by Luca Saldanha Schifino on 22/03/2018.
// Copyright © 2019 4all. All rights reserved.
//

import Foundation

public extension Float {

/// Returns Float's String value with comma and two decimals.
var cleanValue: String {
return String(format: "%.2f",self).replacingOccurrences(of: ".", with: ",")
}
}
33 changes: 33 additions & 0 deletions UtilitiesCore/Extensions/Int+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Int+Extension.swift
// UtilitiesCore
//
// Created by Betina Pereira de Farias on 03/12/18.
// Copyright © 2019 4all. All rights reserved.
//

import Foundation

public extension Int {

/// Returns price String from cents.
var priceStringFromCents: String? {
let formatter = NumberFormatter.brazilianCurrencyFormatter
let amountFloat = Float(self)
let price = amountFloat/100
guard let priceString = formatter.string(from: NSNumber(value: price)) else {
return nil
}
return priceString
}

/// Returns the Int's representation on a badge.
var badgeValue: String? {
if self > 99 {
return "99+"
} else if self <= 0 {
return nil
}
return String(self)
}
}
190 changes: 148 additions & 42 deletions UtilitiesCore/Extensions/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,107 @@

import Foundation

public extension String {
/// Returns a String removing all whitespaces, not only the leading/trailing but also in the middle of the string
var removingWhitespaces: String {
return components(separatedBy: .whitespaces).joined()
}

/// Returns a String removing the leading/trailing whitespaces and new lines
var trimmingWhitespacesAndNewLines: String {
return trimmingCharacters(in: .whitespacesAndNewlines)
}

/// Transform String date from one format to another
///
/// - Parameters:
/// - receivingFormat: actual string date format
/// - transforming: new date format
/// - Returns: String with the new format or nil if fail
func transformDateFormat(_ receivingFormat: String, new transforming: String) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = receivingFormat
let date = dateFormatter.date(from: self)

dateFormatter.dateFormat = transforming

guard let unDate = date else { return nil }
let stringFormatted = dateFormatter.string(from: unDate)

return stringFormatted
}
}

// MARK: - General
public extension String {
/// Returns a String containing only numbers or an empty String
var numbersOnly: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
}

/// Verify if the string has one or more numbers
var hasNumbers: Bool {
return rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil
}

/// Verify if the string has only numbers
var hasOnlyNumbers: Bool {
return rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}

/// Returns a String containing only letters or an empty String
var lettersOnly: String {
return components(separatedBy: CharacterSet.letters.inverted).joined()
}

/// Verify if the string has one or more letters
var hasLetters: Bool {
return rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil
}

/// Verify if the string has only letters
var hasOnlyLetters: Bool {
return rangeOfCharacter(from: CharacterSet.letters.inverted) == nil
}

/// Verify if the string contains at least one letter and one number
var isAlphaNumeric: Bool {
let hasLetters = rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil
let hasNumbers = rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil
let comps = components(separatedBy: .alphanumerics)
return comps.joined(separator: "").isEmpty && hasLetters && hasNumbers
}

/// Returns a String removing all whitespaces, not only the leading/trailing but also in the middle of the string
var removingWhitespaces: String {
return components(separatedBy: .whitespaces).joined()
}

/// Returns a String removing the leading/trailing whitespaces and new lines
var trimmingWhitespacesAndNewLines: String {
return trimmingCharacters(in: .whitespacesAndNewlines)
}

}

// MARK: - Localized
public extension String {

/// Returns localized string from key.
///
/// - Returns: NSLocalizedString
func localized() -> String {
return NSLocalizedString(self, comment: "")
}
}

// MARK: - Date
public extension String {
/// Get Date from string.
///
/// - Parameters:
/// - inputFormat: String's input format. Example: "23/04/2014" is "dd/MM/yyyy"
/// - timezone: TimeZone for the date. If none is passed, the device's locale is used.
/// - Returns: Date
func getDate(withInputFormat inputFormat: String, andTimezoneAbbreviation abbreviation: String? = nil) -> Date? {
let dateFormatter = DateFormatter()
if let abbreviation = abbreviation {
dateFormatter.timeZone = TimeZone(abbreviation: abbreviation)
}
dateFormatter.dateFormat = inputFormat
return dateFormatter.date(from: self)
}

/// Transform String date from one format to another
///
/// - Parameters:
/// - receivingFormat: actual string date format
/// - transforming: new date format
/// - Returns: String with the new format or nil if fail
func transformDateFormat(_ receivingFormat: String, new transforming: String) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = receivingFormat
let date = dateFormatter.date(from: self)

dateFormatter.dateFormat = transforming

guard let unDate = date else { return nil }
let stringFormatted = dateFormatter.string(from: unDate)

return stringFormatted
}
}

// MARK: - Dictionary
public extension String {
/// Dictionary from string JSON format
var toDictionary: [String: Any] {
Expand All @@ -93,6 +123,7 @@ public extension String {
}
}

// MARK: - Currency
public extension String {
/// Get number if string is brazilian currency or return nil
var brazilianCurrencyNumber: NSNumber? {
Expand All @@ -104,6 +135,46 @@ public extension String {
return value
}

/// Get price String amount in cents
var amountCentsFormat: Int? {
let value = self.replacingOccurrences(of: "R$ ", with: "")
.replacingOccurrences(of: ".", with: "")
.replacingOccurrences(of: ",", with: "")
.trimmingCharacters(in: .whitespaces)
guard !value.isEmpty else {
return nil
}
return Int(value)
}

// Formatting text for currency textField
var textFieldCurrencyFormat: String? {
let formatter = NumberFormatter.brazilianCurrencyFormatter
var amountWithPrefix = self

do {
// remove from String: "$", ".", ","
let regex = try NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSRange(location: 0, length: count),
withTemplate: "")
} catch {
return nil
}

let double = (amountWithPrefix as NSString).doubleValue
let number = NSNumber(value: (double / 100))

// if first number is 0 or all numbers were deleted
guard number != 0 else { return nil }
return formatter.string(from: number) ?? nil
}
}

// MARK: - Html
public extension String {

/// Transform string in html format to NSAttributedString with the layout of html
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return NSAttributedString() }
Expand All @@ -114,7 +185,42 @@ public extension String {
return NSAttributedString()
}
}

/// Transform string in html format to NSMutableAttributedString using font and color attributes passed as parameter.
///
/// - Parameters:
/// - font: UIFont to be used.
/// - fontSize: CGFloat for the UIFont's size.
/// - color: UIColor to be used.
/// - Returns: NSMutableAttributedString
func htmlAttributed(using font: String, fontSize: CGFloat, color: UIColor) -> NSMutableAttributedString? {
do {
let htmlCSSString = "<style>" +
"html *" +
"{" +
"font-size: \(fontSize)pt !important;" +
"color: #\(color.hexString ?? "#000") !important;" +
"font-family: \(font), Helvetica !important;" +
"text-align: center;" +
"}</style> \(self)"

guard let data = htmlCSSString.data(using: String.Encoding.utf8) else {
return nil
}

return try NSMutableAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
} catch {
return nil
}
}
}

// MARK: - Range
public extension String {

/// Create a substring based on the range passed
///
/// - Parameter range: range to create the substring
Expand All @@ -123,23 +229,23 @@ public extension String {
let endIndex = self.index(self.startIndex, offsetBy: range.upperBound)
return String(self[startIndex..<endIndex])
}

subscript(range: CountableClosedRange<Int>) -> Substring {
return self[index(at: range.lowerBound)...index(at: range.upperBound)]
}

subscript(range: PartialRangeUpTo<Int>) -> Substring {
return self[..<index(at: range.upperBound)]
}

subscript(range: PartialRangeThrough<Int>) -> Substring {
return self[...index(at: range.upperBound)]
}

subscript(range: PartialRangeFrom<Int>) -> Substring {
return self[index(at: range.lowerBound)...]
}

internal func index(at offset: Int) -> String.Index {
return index(startIndex, offsetBy: offset)
}
Expand Down
Loading

0 comments on commit fddf820

Please sign in to comment.