From 6f7a9ddfe35ce690ed20631baa984af8b99a49af Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Tue, 25 Apr 2017 15:49:43 +0200 Subject: [PATCH 01/10] fix to get the system's language by default and not the language bundle --- Sources/Localize.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Localize.swift b/Sources/Localize.swift index 278240f..74b2c5e 100644 --- a/Sources/Localize.swift +++ b/Sources/Localize.swift @@ -131,7 +131,7 @@ open class Localize: NSObject { */ open class func defaultLanguage() -> String { var defaultLanguage: String = String() - guard let preferredLanguage = Bundle.main.preferredLocalizations.first else { + guard let preferredLanguage = Locale.current.languageCode else { return LCLDefaultLanguage } let availableLanguages: [String] = self.availableLanguages() From fabb7e2870831812f4435c1ec7e44e783569292c Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 10:06:31 +0200 Subject: [PATCH 02/10] add method to localize attributed string with pseudo code --- Sources/String+LocalizeAttributed.swift | 90 +++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Sources/String+LocalizeAttributed.swift diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift new file mode 100644 index 0000000..7b5b1c4 --- /dev/null +++ b/Sources/String+LocalizeAttributed.swift @@ -0,0 +1,90 @@ +// +// String+LocalizeAttributed.swift +// Localize_Swift +// +// Created by Smol on 10/05/2017. +// Copyright © 2017 Roy Marmelstein. All rights reserved. +// + +import Foundation +import UIKit + +// example - #[{color:3A92C4;background:00FF00}bleue] + +fileprivate extension UIColor { + convenience init(hexa: Int) { + let red : Int = hexa >> 16 & 0xFF + let green : Int = hexa >> 8 & 0xFF + let blue : Int = hexa & 0xFF + + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) + } +} + +public extension String { + internal func substring(from range : NSRange) -> String { + let startIndex = self.index(self.startIndex, offsetBy: range.location) + let endIndex = self.index(self.startIndex, offsetBy: range.location + range.length) + + let newRange = startIndex.. NSMutableAttributedString { + let mutable : NSMutableAttributedString = NSMutableAttributedString(string: self, attributes: nil) + + let pattern : String = "\\#\\[\\{(.+)\\}(.+)\\]" + let regexp = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) + + let matches : [NSTextCheckingResult] = regexp.matches(in: self, options: [], range: NSMakeRange(0, self.characters.count)) + + for match in matches { + let group = match.rangeAt(0) + let styles = match.rangeAt(1) + let text = match.rangeAt(2) + + let temp = parse(style: self.substring(from: styles)) + + mutable.replaceCharacters(in: group, with: self.substring(from: text)) + + mutable.addAttributes(temp, range: NSMakeRange(group.location, text.length)) + } + + return mutable + } + + func parse(style: String) -> [String:Any]{ + var attributes : [String:Any] = [:] + let pattern : String = "[;]?([^;:]+):([^;:}]+)" + + let regexp = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) + + let matches : [NSTextCheckingResult] = regexp.matches(in: style, options: [], range: NSMakeRange(0, style.characters.count)) + + for match in matches { + let key = style.substring(from: match.rangeAt(1)) + let value = style.substring(from: match.rangeAt(2)) + + + let temp = self.attribute(key: key, value: value) + attributes[temp.key] = temp.value + } + + return attributes + } + + func attribute(key: String, value: String) -> (key: String, value: Any) { + switch key { + case "color": + return (key: NSForegroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) + case "background": + return (key: NSBackgroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) + default: + return (key: "", value: "") + } + } +} From 304784266192d9be8c754d2f632fe6f85238c475 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 10:08:46 +0200 Subject: [PATCH 03/10] update podspec's version --- Localize-Swift.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localize-Swift.podspec b/Localize-Swift.podspec index 82b0526..db5fbbc 100644 --- a/Localize-Swift.podspec +++ b/Localize-Swift.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = "Localize-Swift" - s.version = "1.7.1" + s.version = "1.7.2" s.summary = "Swift-friendly localization and i18n syntax with in-app language switching." # This description is used to generate tags and improve search results. From 8cd000ffe3517ff2fdb711aa3a1ed7b468461d02 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 10:22:24 +0200 Subject: [PATCH 04/10] change visibility --- Sources/String+LocalizeAttributed.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index 7b5b1c4..a2d80d0 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -30,7 +30,7 @@ public extension String { return self.substring(with: newRange) } - var localizedAttributed : NSMutableAttributedString { + public var localizedAttributed : NSMutableAttributedString { return self.transform() } From 8b14789e66d687cc909f788ef601d7ff5765c6ca Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 10:42:15 +0200 Subject: [PATCH 05/10] call localised to work correctly --- Sources/String+LocalizeAttributed.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index a2d80d0..c758882 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -31,7 +31,7 @@ public extension String { } public var localizedAttributed : NSMutableAttributedString { - return self.transform() + return self.localized().transform() } private func transform() -> NSMutableAttributedString { From 5ef7e680007b79d3b6a01a5b18ea43b87578c690 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 12:14:19 +0200 Subject: [PATCH 06/10] improve localise attributed behaviour --- Sources/String+LocalizeAttributed.swift | 41 +++++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index c758882..a7cde7d 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -34,26 +34,39 @@ public extension String { return self.localized().transform() } - private func transform() -> NSMutableAttributedString { - let mutable : NSMutableAttributedString = NSMutableAttributedString(string: self, attributes: nil) - - let pattern : String = "\\#\\[\\{(.+)\\}(.+)\\]" + private func parse(mutable: NSMutableAttributedString) -> NSMutableAttributedString { + var tempMutable = mutable + let pattern : String = "\\#\\[\\{([^\\}]+)\\}(.+)\\]" let regexp = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) - let matches : [NSTextCheckingResult] = regexp.matches(in: self, options: [], range: NSMakeRange(0, self.characters.count)) + + let matches : [NSTextCheckingResult] = regexp.matches(in: mutable.string, options: [], range: NSMakeRange(0, mutable.string.characters.count)) for match in matches { let group = match.rangeAt(0) let styles = match.rangeAt(1) let text = match.rangeAt(2) - - let temp = parse(style: self.substring(from: styles)) - mutable.replaceCharacters(in: group, with: self.substring(from: text)) + let temp = parse(style: mutable.string.substring(from: styles)) + + tempMutable.replaceCharacters(in: group, with: mutable.string.substring(from: text)) + + tempMutable.addAttributes(temp, range: NSMakeRange(group.location, text.length)) + tempMutable = self.parse(mutable: tempMutable) - mutable.addAttributes(temp, range: NSMakeRange(group.location, text.length)) } + return tempMutable + } + + private func transform() -> NSMutableAttributedString { + var mutable : NSMutableAttributedString = NSMutableAttributedString(string: self, attributes: nil) + + mutable.beginEditing() + + mutable = self.parse(mutable: mutable) + + mutable.endEditing() return mutable } @@ -64,7 +77,7 @@ public extension String { let regexp = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) let matches : [NSTextCheckingResult] = regexp.matches(in: style, options: [], range: NSMakeRange(0, style.characters.count)) - + for match in matches { let key = style.substring(from: match.rangeAt(1)) let value = style.substring(from: match.rangeAt(2)) @@ -83,6 +96,14 @@ public extension String { return (key: NSForegroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) case "background": return (key: NSBackgroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) + case "font": + let temp = value.components(separatedBy: ",") + return (key: NSFontAttributeName, value: UIFont(name: temp[0], size: CGFloat(Int.init(temp[1], radix: 10) ?? Int(UIFont.systemFontSize)))) + case "align": + let paragraphStyle : NSMutableParagraphStyle = NSMutableParagraphStyle() + + paragraphStyle.alignment = .center + return (key: NSParagraphStyleAttributeName, value: paragraphStyle) default: return (key: "", value: "") } From d61dcad2ab7d77d072140f3e31047d97e00625a1 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 13:24:01 +0200 Subject: [PATCH 07/10] patch --- Sources/String+LocalizeAttributed.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index a7cde7d..32bd034 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -30,8 +30,8 @@ public extension String { return self.substring(with: newRange) } - public var localizedAttributed : NSMutableAttributedString { - return self.localized().transform() + public var attributed : NSMutableAttributedString { + return self.transform() } private func parse(mutable: NSMutableAttributedString) -> NSMutableAttributedString { From e834c30401b6cbfbe2fbb237a99589563e98ac66 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Wed, 10 May 2017 13:36:24 +0200 Subject: [PATCH 08/10] fix warning --- Sources/String+LocalizeAttributed.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index 32bd034..37845b8 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -98,7 +98,12 @@ public extension String { return (key: NSBackgroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) case "font": let temp = value.components(separatedBy: ",") - return (key: NSFontAttributeName, value: UIFont(name: temp[0], size: CGFloat(Int.init(temp[1], radix: 10) ?? Int(UIFont.systemFontSize)))) + + guard let font = UIFont(name: temp[0], size: CGFloat(Int.init(temp[1], radix: 10) ?? Int(UIFont.systemFontSize))) else { + return (key: "", value: "") + } + + return (key: NSFontAttributeName, value: font) case "align": let paragraphStyle : NSMutableParagraphStyle = NSMutableParagraphStyle() From a8a66e62a5c7f97378e7f5f064b947cfed36a203 Mon Sep 17 00:00:00 2001 From: Julien Smolareck Date: Thu, 9 Aug 2018 19:24:33 +0200 Subject: [PATCH 09/10] swift 3.3 to 4.1 --- Localize_Swift.xcodeproj/project.pbxproj | 4 ++-- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 Localize_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Localize_Swift.xcodeproj/project.pbxproj b/Localize_Swift.xcodeproj/project.pbxproj index 4677bae..8f4d671 100644 --- a/Localize_Swift.xcodeproj/project.pbxproj +++ b/Localize_Swift.xcodeproj/project.pbxproj @@ -470,7 +470,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -514,7 +514,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; diff --git a/Localize_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Localize_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Localize_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + From 4051ca0749e9a3fc2e9ce177a87e6ff637e2c227 Mon Sep 17 00:00:00 2001 From: smol Date: Thu, 9 Aug 2018 19:46:23 +0200 Subject: [PATCH 10/10] changes for swift 4 --- Localize_Swift.xcodeproj/project.pbxproj | 4 ++++ Sources/String+LocalizeAttributed.swift | 29 ++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Localize_Swift.xcodeproj/project.pbxproj b/Localize_Swift.xcodeproj/project.pbxproj index 8f4d671..0af577c 100644 --- a/Localize_Swift.xcodeproj/project.pbxproj +++ b/Localize_Swift.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2ED39529211CB405000723E6 /* String+LocalizeAttributed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED39528211CB405000723E6 /* String+LocalizeAttributed.swift */; }; 3433F2411C518AF7003AE34D /* Localize_Swift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3433F2361C518AF7003AE34D /* Localize_Swift.framework */; }; 3433F2461C518AF7003AE34D /* Localize_SwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3433F2451C518AF7003AE34D /* Localize_SwiftTests.swift */; }; 3433F2521C518B38003AE34D /* Localize_Swift.h in Headers */ = {isa = PBXBuildFile; fileRef = 3433F2501C518B38003AE34D /* Localize_Swift.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -46,6 +47,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 2ED39528211CB405000723E6 /* String+LocalizeAttributed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+LocalizeAttributed.swift"; path = "Sources/String+LocalizeAttributed.swift"; sourceTree = SOURCE_ROOT; }; 3433F2361C518AF7003AE34D /* Localize_Swift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Localize_Swift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3433F23B1C518AF7003AE34D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3433F2401C518AF7003AE34D /* Localize_SwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Localize_SwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -131,6 +133,7 @@ 3433F2381C518AF7003AE34D /* Localize_Swift */ = { isa = PBXGroup; children = ( + 2ED39528211CB405000723E6 /* String+LocalizeAttributed.swift */, 3433F2501C518B38003AE34D /* Localize_Swift.h */, 3433F2511C518B38003AE34D /* Localize.swift */, 68A520031DA6D5FD00F43D9E /* String+LocalizeTableName.swift */, @@ -367,6 +370,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2ED39529211CB405000723E6 /* String+LocalizeAttributed.swift in Sources */, 68973D6B1DA7AB140076F08A /* String+LocalizedBundleTableName.swift in Sources */, 68973D661DA7AA200076F08A /* String+LocalizeBundle.swift in Sources */, 3433F2531C518B38003AE34D /* Localize.swift in Sources */, diff --git a/Sources/String+LocalizeAttributed.swift b/Sources/String+LocalizeAttributed.swift index 37845b8..036173e 100644 --- a/Sources/String+LocalizeAttributed.swift +++ b/Sources/String+LocalizeAttributed.swift @@ -43,9 +43,9 @@ public extension String { let matches : [NSTextCheckingResult] = regexp.matches(in: mutable.string, options: [], range: NSMakeRange(0, mutable.string.characters.count)) for match in matches { - let group = match.rangeAt(0) - let styles = match.rangeAt(1) - let text = match.rangeAt(2) + let group = match.range(at: 0) + let styles = match.range(at: 1) + let text = match.range(at: 2) let temp = parse(style: mutable.string.substring(from: styles)) @@ -70,8 +70,8 @@ public extension String { return mutable } - func parse(style: String) -> [String:Any]{ - var attributes : [String:Any] = [:] + func parse(style: String) -> [NSAttributedStringKey:Any]{ + var attributes : [NSAttributedStringKey:Any] = [:] let pattern : String = "[;]?([^;:]+):([^;:}]+)" let regexp = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) @@ -79,8 +79,8 @@ public extension String { let matches : [NSTextCheckingResult] = regexp.matches(in: style, options: [], range: NSMakeRange(0, style.characters.count)) for match in matches { - let key = style.substring(from: match.rangeAt(1)) - let value = style.substring(from: match.rangeAt(2)) + let key = style.substring(from: match.range(at: 1)) + let value = style.substring(from: match.range(at: 2)) let temp = self.attribute(key: key, value: value) @@ -90,27 +90,28 @@ public extension String { return attributes } - func attribute(key: String, value: String) -> (key: String, value: Any) { + func attribute(key: String, value: String) -> (key: NSAttributedStringKey, value: Any) { switch key { case "color": - return (key: NSForegroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) + + return (key: NSAttributedStringKey.foregroundColor, value: UIColor(hexa: Int.init(value, radix: 16)!)) case "background": - return (key: NSBackgroundColorAttributeName, value: UIColor(hexa: Int.init(value, radix: 16)!)) + return (key: NSAttributedStringKey.backgroundColor, value: UIColor(hexa: Int.init(value, radix: 16)!)) case "font": let temp = value.components(separatedBy: ",") guard let font = UIFont(name: temp[0], size: CGFloat(Int.init(temp[1], radix: 10) ?? Int(UIFont.systemFontSize))) else { - return (key: "", value: "") + return (key: NSAttributedStringKey.init(""), value: "") } - return (key: NSFontAttributeName, value: font) + return (key: NSAttributedStringKey.font, value: font) case "align": let paragraphStyle : NSMutableParagraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .center - return (key: NSParagraphStyleAttributeName, value: paragraphStyle) + return (key: NSAttributedStringKey.paragraphStyle, value: paragraphStyle) default: - return (key: "", value: "") + return (key: NSAttributedStringKey.init(""), value: "") } } }