Swift checking String for guid value - ios

I receive from my web service an authorisation string, that represents a Guid (C#). How I can convert string into guid using Swift? Or, how I can validate result, that it is, in fact, a Guid?
var str1:String = "5810744d-49f7-4edc-aefb-ecd1ebf9e59b"
var str2:String = "Some text"
How i can define - is string contains guid?

You can use NSPredicate with a regex to see if a string is in the correct format:
var str1:String = "(5810744d-49f7-4edc-aefb-ecd1ebf9e59b)"
var str2:String = "Some text"
let guidPred = NSPredicate(format: "SELF MATCHES %#", "((\\{|\\()?[0-9a-f]{8}-?([0-9a-f]{4}-?){3}[0-9a-f]{12}(\\}|\\))?)|(\\{(0x[0-9a-f]+,){3}\\{(0x[0-9a-f]+,){7}0x[0-9a-f]+\\}\\})")
// Prints "str1 IS a GUID"
if guidPred.evaluateWithObject(str1) {
println("str1 IS a GUID")
} else {
println("str1 is NOT a GUID")
}
// Prints "str2 is NOT a GUID"
if guidPred.evaluateWithObject(str2) {
println("str2 IS a GUID")
} else {
println("str2 is NOT a GUID")
}
This regex will match any of the four formats listed on MSDN. To keep it (relatively) simple, the expression will match some ill-formatted strings (such as if you were to delete one hyphen, but not all the others: 5810744d49f7-4edc-aefb-ecd1ebf9e59b), but will filter out regular text.

Related

How to split uncode string into characters

I have strings like
"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8",
"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb",
"\U0aa6\U0abe\U0ab5\U0acb",
"\U0a96\U0a82\U0aa1"
But I want to split this strings by unicode character
I dont know hot to do. I know components seprated by function but it's no use here.
\nAny help would be apperiaciated
If the strings you're getting really contain \U characters, you need to parse them manually and extract the unicode scalar values. Something like this:
let strings = [
"\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8",
"\\U0a97\\U0ac1\\U0ab8\\U0acd\\U0ab8\\U0acb",
"\\U0aa6\\U0abe\\U0ab5\\U0acb",
"\\U0a96\\U0a82\\U0aa1"
]
for str in strings {
let chars = str.components(separatedBy: "\\U")
var string = ""
for ch in chars {
if let val = Int(ch, radix: 16), let uni = Unicode.Scalar(val) {
string.unicodeScalars.append(uni)
}
}
print(string)
}
You can map your array, split its elements at non hexa digit values, compact map them into UInt32 values, initializate unicode scalars with them and map the resulting elements of your array into a UnicodeScalarView and init a new string with it:
let arr = [
#"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8"#,
#"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb"#,
#"\U0aa6\U0abe\U0ab5\U0acb"#,
#"\U0a96\U0a82\U0aa1"#]
let strings = arr.map {
$0.split { !$0.isHexDigit }
.compactMap { UInt32($0, radix: 16) }
.compactMap(Unicode.Scalar.init)
}.map { String(String.UnicodeScalarView($0)) }
print(strings)
This will print
["બહુવચન", "ગુસ્સો", "દાવો", "ખંડ"]
So, the string that comes back already has the "\" because in order to use components you'd need to have an additional escaping "\" so that you'd be able to do:
var listofCodes = ["\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8", "\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8"]
var unicodeArray :[String] = []
listofCodes.forEach { string in
unicodeArray
.append(contentsOf: string.components(separatedBy: "\\"))
unicodeArray.removeAll(where: {value in value == ""})
}
print(unicodeArray)
I will revise this answer once you specify how you are obtaining these strings, as is I get a non-valid string error from the start.

Remove special characters from the string

I am trying to use an iOS app to dial a number. The problem is that the number is in the following format:
po placeAnnotation.mapItem.phoneNumber!
"‎+1 (832) 831-6486"
I want to get rid of some special characters and I want the following:
832-831-6486
I used the following code but it did not remove anything:
let charactersToRemove = CharacterSet(charactersIn: "()+-")
var telephone = placeAnnotation.mapItem.phoneNumber?.trimmingCharacters(in: charactersToRemove)
Any ideas?
placeAnnotation.mapItem.phoneNumber!.components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
Here you go!
I tested and works well.
If you want something similar to CharacterSet with some flexibility, this should work:
let phoneNumber = "1 (832) 831-6486"
let charsToRemove: Set<Character> = Set("()+-".characters)
let newNumberCharacters = String(phoneNumber.characters.filter { !charsToRemove.contains($0) })
print(newNumberCharacters) //prints 1 832 8316486
I know the question is already answered, but to format phone numbers in any way one could use a custom formatter like below
class PhoneNumberFormatter:Formatter
{
var numberFormat:String = "(###) ### ####"
override func string(for obj: Any?) -> String? {
if let number = obj as? NSNumber
{
var input = number as Int64
var output = numberFormat
while output.characters.contains("#")
{
if let range = output.range(of: "#", options: .backwards)
{
output = output.replacingCharacters(in: range, with: "\(input % 10)")
input /= 10
}
else
{
output.replacingOccurrences(of: "#", with: "")
}
}
return output
}
return nil
}
func string(from number:NSNumber) -> String?
{
return string(for: number)
}
}
let phoneNumberFormatter = PhoneNumberFormatter()
//Digits will be filled backwards in place of hashes. It is easy change the custom formatter in anyway
phoneNumberFormatter.numberFormat = "###-##-##-##-##"
phoneNumberFormatter.string(from: 18063783889)
Swift 3
func removeSpecialCharsFromString(_ str: String) -> String {
struct Constants {
static let validChars = Set("1234567890-".characters)
}
return String(str.characters.filter { Constants.validChars.contains($0) })
}
To Use
let str : String = "+1 (832) 831-6486"
let newStr : String = self.removeSpecialCharsFromString(str)
print(newStr)
Note: you can add validChars which you want in string after operation perform.
If you have the number and special character in String format the use following code to remove special character
let numberWithSpecialChar = "1800-180-0000"
let actulNumber = numberWithSpecialChar.components(separatedBy: CharcterSet.decimalDigit.inverted).joined()
Otherwise, If you have the characters and special character in String format the use following code to remove special character
let charactersWithSpecialChar = "A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal-Panama!"
let actulString = charactersWithSpecialChar.components(separatedBy: CharacterSet.letters.inverted).joined(separator: " ")
NSString *str = #"(123)-456-7890";
NSLog(#"String: %#", str);
// Create character set with specified characters
NSMutableCharacterSet *characterSet =
[NSMutableCharacterSet characterSetWithCharactersInString:#"()-"];
// Build array of components using specified characters as separtors
NSArray *arrayOfComponents = [str componentsSeparatedByCharactersInSet:characterSet];
// Create string from the array components
NSString *strOutput = [arrayOfComponents componentsJoinedByString:#""];
NSLog(#"New string: %#", strOutput);

swift text with 2 variables and different language

i would like to translate a string, which have two variables inside.
at the moment, i use for translating this code:
NSLocalizedString("Name_In_Langauge_String_File",comment:"")
but how can i translate the following string?
This is a test with 100 Pictures and 50 Users
where 100 and 50 are variables.
Put this in you Localizable.strings:
"Name_In_Langauge_String_File" = "This is a test with %d Pictures and %d Users";
and in your code:
String.localizedStringWithFormat(
NSLocalizedString("Name_In_Langauge_String_File",
comment: ""),
pictures,
users)
In a project I was working on I noticed that we kept repeating the code to do the string formatting for the localization file. This meant you could not just use the value, you first needed to check what parameters were required. One way to avoid this problem is to use Swift enums. This method is also useful for unit testing your localizations.
Assume you have the following 3 localizations in your strings file:
"TestNoParams" = "This is a test message";
"TestOneParam" = "Hello %#";
"TestTwoParams" = "This is a test with %d Pictures and %d Users";
Now you can use the following enum, protocol and extension to reference your strings:
protocol LocalizationProtocol {
var key: String { get }
var value: String { get }
}
extension LocalizationProtocol {
private func localizationValue() -> String {
return NSLocalizedString(key, comment:key)
}
private func localizationValueWithFormat(parameters: CVarArgType...) -> String {
return String(format: localizationValue(), arguments: parameters)
}
}
enum Localizations: LocalizationProtocol {
case TestNoParams
case TestOneParam(name: String)
case TestPicturesAndUsers(pictures: Int, users: Int)
var key: String {
switch self {
case .TestNoParams: return "TestNoParams"
case .TestOneParam: return "TestOneParam"
case .TestPicturesAndUsers: return "TestTwoParams"
}
}
var value: String {
switch self {
case .TestOneParam(let name):
return localizationValueWithFormat(name)
case .TestPicturesAndUsers(let pictures, let users):
return localizationValueWithFormat(pictures, users)
default:
return localizationValue()
}
}
}
Now to use it you just need to call the enums value method:
let testNoParam = Localizations.TestNoParams.value
let testOneParam = Localizations.TestOneParam(name: "users name").value
let testTwoParams = Localizations.TestPicturesAndUsers(pictures: 4, users: 500).value
The example I have shown is simplified, but you can also nest enums to provide a nice grouping for your localizations. For instance you could have your enums nested by ViewController. This is an example for a welcome message: Localizations.Main.WelcomeMessage.value

Replace part of string with lower case letters - Swift

I have a Swift based iOS app and one of the features allows you to comment on a post. Anyway, users can add "#mentions" in their posts to tag other people. However I want to stop the user from adding a username with a capital letter.
Is there anyway I can convert a string, so that the #usernames are all in lowercase?
For example:
I really enjoy sightseeing with #uSerABC (not allowed)
I really enjoy sightseeing with #userabc (allowed)
I know there is a property for the string in swift called .lowercaseString - but the problem with that, is that it makes the entire string lowercase and thats not what I want. I only want the #username to be in lower case.
Is there any way around this with having to use the .lowercase property.
Thanks for your time, Dan.
This comes from a code I use to detect hashtags, I've modified to detect mentions:
func detectMentionsInText(text: String) -> [NSRange]? {
let mentionsDetector = try? NSRegularExpression(pattern: "#(\\w+)", options: NSRegularExpressionOptions.CaseInsensitive)
let results = mentionsDetector?.matchesInString(text, options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, text.utf16.count)).map { $0 }
return results?.map{$0.rangeAtIndex(0)}
}
It detects all the mentions in a string by using a regex and returns an NSRange array, by using a range you have the beginning and the end of the "mention" and you can easily replace them with a lower case version.
Split the string into two using the following command -
let arr = myString.componentsSeparatedByString("#")
//Convert arr[1] to lower case
//Append to arr[0]
//Enjoy
Thanks to everyone for their help. In the end I couldn't get any of the solutions to work and after a lot of testing, I came up with this solution:
func correctStringWithUsernames(inputString: String, completion: (correctString: String) -> Void) {
// Create the final string and get all
// the seperate strings from the data.
var finalString: String!
var commentSegments: NSArray!
commentSegments = inputString.componentsSeparatedByString(" ")
if (commentSegments.count > 0) {
for (var loop = 0; loop < commentSegments.count; loop++) {
// Check the username to ensure that there
// are no capital letters in the string.
let currentString = commentSegments[loop] as! String
let capitalLetterRegEx = ".*[A-Z]+.*"
let textData = NSPredicate(format:"SELF MATCHES %#", capitalLetterRegEx)
let capitalResult = textData.evaluateWithObject(currentString)
// Check if the current loop string
// is a #user mention string or not.
if (currentString.containsString("#")) {
// If we are in the first loop then set the
// string otherwise concatenate the string.
if (loop == 0) {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = currentString.lowercaseString
}
else {
// The username does not contain capital letters.
finalString = currentString
}
}
else {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = "\(finalString) \(currentString.lowercaseString)"
}
else {
// The username does not contain capital letters.
finalString = "\(finalString) \(currentString)"
}
}
}
else {
// The current string is NOT a #user mention
// so simply set or concatenate the finalString.
if (loop == 0) {
finalString = currentString
}
else {
finalString = "\(finalString) \(currentString)"
}
}
}
}
else {
// No issues pass back the string.
finalString = inputString
}
// Pass back the correct username string.
completion(correctString: finalString)
}
Its certainly not the most elegant or efficient solution around but it does work. If there are any ways of improving it, please leave a comment.

Check if string is 3 chars and 3 number in Swift

I'm trying to create a function that validate my string if it is using this format
ABC123
First three characters should be letters and the other 3 should be numbers
I have no idea on how to start
Thanks
You can do it with a regular expression match on strings, like this:
let str = "ABC123"
let optRange = str.rangeOfString("^[A-Za-z]{3}\\d{3}$", options: .RegularExpressionSearch)
if let range = optRange {
println("Matched")
} else {
println("Not matched")
}
Regex above requires that the match occupied the whole string (the ^ and $ anchors at both ends), has three letters [A-Za-z]{3} and three digits \\d{3}.
You can also use it as an extension if you would like to:
extension String {
var match: Bool {
return rangeOfString("^[A-Za-z]{3}\\d{3}$", options: .RegularExpressionSearch) != nil
}
}
"ABC123".match // true

Resources