Get string of all possible characters given iOS keyboard language - ios

I'm trying to verify that every character in a text box is limited to the language's keyboard options. This means that in English, you would only be able to type characters which are accessible through the iOS keyboard. If there is a string containing all characters, or a code solution - either will work.
Thanks for the help.

Try something like this. Let me know if it helped :) Good luck!
let letters = CharacterSet.letters
let text = textField.text
let range = text.rangeOfCharacters(from: letters)
if range != nil {
// Yay it's correct
}else{
// Oh no
}
The CharacterSet documentation has multiple options for the characters you want to restrict the field to. You can even make your own character sets! Check out the link: https://developer.apple.com/documentation/foundation/characterset

You could check it like that (is Swift):
let charactersSet = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
if yourString.rangeOfCharacter(from: charactersSet.inverted) != nil {
print("string contains special characters")
}

You can try some thing like:
NSString *inputString = #"abc0129yourcontent";
BOOL success = [inputString isMatchedByRegex:#"^[0-9a-zA-Z]+$"];
You can convert in Swift if required.

Related

UITextField for nickname

I need to set UITextField for nickname. It need to be english only, lowercase, underscore and numbers. Really don't know how to do that and can't find any information. Thanks for your time!
you can create a regex for this & comparison textfield value with your regex pattern.
func isValidName(name:String)-> Bool {
let nameRegEx = "^[a-z0-9_]+$" // this mean you can only use lower case a-z, 0-9 and underscore
let namelTest = NSPredicate(format:"SELF MATCHES %#", nameRegEx)
return namelTest.evaluate(with: name)
}
use this method and vaidate textfield value by pasting as parameter function.
if return true it means username passed validation.
if return false you can show an error to user or shake textfiled and set red color for textfield.text or placeholder color or any thing you want.
hope to this help you.

Checking if first 3 characters of UI TextField are numeric in Swift

I want to check if the first three characters entered in the UI Textfield are numbers. I could do this easily in Python, but for some reason in Swift it's a pain.
Here's my python if statements (which I want to 'translate' into swift as it works):
str = "123abc"
if str.isdigit():
if str[:3]:
print(str)
and here's my swift code
#IBOutlet weak var input: UITextField!
#IBAction func checkBarcodeRegion(_ sender: UIButton)
{
let text: String = input.text!
if text.prefix(3)
{
//if numeric
//do something
}
}
Can't get this to work. Any help appreciated.
Three alternatives:
Create an Int from the substring and check if for non-nil.
let isNumeric1 = Int(text.prefix(3)) != nil
Remove all digits from the substring with Regular Expression and check for empty string
let isNumeric2 = text.prefix(3).replacingOccurrences(of: "[0-9]", with: "", options: .regularExpression).isEmpty
Split the substring by the decimalDigits character set and check if the number of components is 4
let isNumeric3 = text.prefix(3).components(separatedBy: .decimalDigits).count == 4
Using prefix is the right direction to go. You can use allSatisfy after that to check if they are all digits. One of the ways to check for digits is to check if the unicode scalar is in the CharacterSet.decimalDigits set.
text.unicodeScalars.prefix(3)
.allSatisfy(CharacterSet.decimalDigits.contains)
This will check for all the digits in Unicode, including the ones that the Indians and Arabic use.
If by digits you mean the ASCII 0123456789, then you could use:
text.prefix(3).allSatisfy(("0"..."9").contains)

Using lowercaseString in Swift with the "İ" character

In my app, I use lowercaseString. When I change "İ" to lowercase, the output is incorrect. It puts more points on the smaller letters:
let isim = "titTTSSİŞÇÖÜİİİle".lowercaseString
The output is:
titttssi̇şçöüi̇i̇i̇le
The correct output for İ should be i
It looks like this is Turkish text. You can use lowercaseStringWithLocale to handle this correctly:
4> let isim = "titTTSSİŞÇÖÜİİİle".lowercaseStringWithLocale(NSLocale(localeIdentifier: "tr"))
isim: String = "titttssişçöüiiile"
You may wish to use NSLocale.currentLocale instead, to accommodate users in different locales based on their preferences.
You may have to change that character separately. Perhaps something like this:
var isim: NSString = "titTTSSİŞÇÖÜİİİle".lowercaseString
isim = isim.stringByReplacingOccurrencesOfString("İ", withString: "i")
Hope this helps.

How to extract emojis from a string?

I'm looking for a way to take a String and extract Emoji characters.
I know that Emojis are part of Unicode so I need to remove a certain subset of Unicode characters. I don't really know where to start.
The Set of Emoji characters
First of all we need a Set containing the unicode values representing the emoji.
Disclaimer
For this answer I am using the range of Emoticons (1F601-1F64F) and Dingbats (2702-27B0) to show you the solution. However keep in mind that you should add further ranges depending on your needs.
Extending Character
Now we need a way to calculate the Unicode Scalar Code Point of a Character. For this I am using the solution provided here.
extension Character {
private var unicodeScalarCodePoint: Int {
let characterString = String(self)
let scalars = characterString.unicodeScalars
return Int(scalars[scalars.startIndex].value)
}
}
Extending String
This extension does allow you to extract the emoji characters from a String.
extension String {
var emojis:[Character] {
let emojiRanges = [0x1F601...0x1F64F, 0x2702...0x27B0]
let emojiSet = Set(emojiRanges.flatten())
return self.characters.filter { emojiSet.contains($0.unicodeScalarCodePoint) }
}
}
Testing
let sentence = "😃 hello world 🙃"
sentence.emojis // ["😃", "🙃"]

How to use autocorrection and shortcut list in iOS8 custom keyboard?

I want to use the autocorrection and shortcut list like default English keyboard with my custom keyboard.
I check the in keyboard document but don't know how to use it.
In keyboard documentation.
Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon object contains words from various sources, including:
Unpaired first names and last names from the user’s Address Book database
Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list
A common words dictionary
How to access shortcut list and input from our dictionary in Objective-C?
How to use UILexicon with requestSupplementaryLexiconWithCompletion?
Implementing the lexicon would look pretty much like this:
Use requestSupplementaryLexiconWithCompletion() to get the lexicon upon launch once.
Each type text is inputted add it to a NSString (tracking the current word)
When user presses space (end of curent word) check the string against the lexicon
If it's a match count the number of characters and delete that number of characters
Input the suggestion suggested by the lexicon
Clear the string and start again
Additionally you could also use UITextChecker to offer more advanced auto-correct features.
Code (in Objective-C, this may not be 100% accurate I wrote in SO while on the bus but it should do):
UILexicon *lexicon;
NSString *currentString;
-(void)viewDidLoad {
[self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
self.lexicon = receivedLexicon;
}];
}
-(IBAction)myTypingAction:(UIButton *)sender {
[documentProxy insertText:sender.title];
[currentString stringByAppendingString:sender.title];
}
-(IBAction)space {
[documentProxy insertText:#" "];
for (UILexiconEntry *lexiconEntry in lexicon.entries) {
if (lexiconEntry.userInput isEqualToString:currentString) {
for (int i = 0; currentString.length >=i ; i++) {
[documentProxy deleteTextBackwards];
}
[documentProxy insertText:lexiconEntry.documentText];
currentString = #"";
}
}
}
Feel free to comment if you have any more questions.
Source: Personal experience with iOS 8 keyboards and UILexicon
With regards to auto-correction, I was able to add it using link. Here's the code snippet I used from the link:
UITextChecker *checker = [[UITextChecker alloc] init];
NSRange checkRange = NSMakeRange(0, self.txView.text.length);
NSRange misspelledRange = [checker rangeOfMisspelledWordInString:self.txView.text
range:checkRange
startingAt:checkRange.location
wrap:NO
language:#"en_US"];
NSArray *arrGuessed = [checker guessesForWordRange:misspelledRange inString:self.txView.text language:#"en_US"];
self.txView.text = [self.txView.text stringByReplacingCharactersInRange:misspelledRange
withString:[arrGuessed objectAtIndex:0]];
The full documentation from Apple can be found here.
Although I have not personally tried creating a custom keyboard, I am basing this answer on what I can see in the documentation.
In your keyboard, create a property called entries of type [AnyObject] (Array of AnyObjects).
In your init method, or wherever you create the keyboard, call this method:
requestSupplementaryLexiconWithCompletion(completionHandler: {
lexicon in
self.entries = lexicon.entries
})
I suspect that entries is actually an array of Strings or NSStrings, but it could be a dictionary or some other type. When testing this out, try figuring out what type is actually contained in entries before figuring out your logic.
I do not believe there is a way to get Apple's default autocorrect options currently. However, this WWDC talk gives insight about how they made autocorrect work in the original iPhone OS (around the 30 minute mark).
He mentions using a binary search of the array, which leads me to believe that this array is sorted. Of course, much could have changed since the first iPhone came out...
Good luck figuring out this new API!
This is the way you can actually access Lexicon words:
[self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
self.lexicon = receivedLexicon;
for (UILexiconEntry *word in self.lexicon.entries) {
// Text to be inserted into a text input object by a custom keyboard, corresponding to the userInput value in the same lexicon entry.
NSLog(#"%#",word.documentText);
// Text to match, during user input, to provide appropriate output to a text document from the documentText value in the same lexicon entry.
NSLog(#"%#",word.userInput);
}
}];
Rachits answer above in swift 4. Works with iOS 12
I have this helper to check wether the current string to be tested by UITextChecker is not a space
func validate(string: String?) -> Bool {
guard let text = string,
!text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty else {
return false
}
return true
}
The text checker is then in my "Spacebar", "Spacebar double tapped" & "return" methods. The example below is in my "Space" method
let textChecker = UITextChecker()
let currentString = self.textDocumentProxy.documentContextBeforeInput
if validate(string: currentString) {
let charSet = NSCharacterSet.whitespacesAndNewlines
let components = currentString?.components(separatedBy: charSet)
let lastWord = components?.last
let checkRange = NSMakeRange(0, lastWord?.count ?? 0)
let misspelledRange = textChecker.rangeOfMisspelledWord(in: lastWord!, range: checkRange, startingAt: checkRange.location, wrap: false, language: "en_US")
if misspelledRange.length != 0 {
let guessedWord: Array = textChecker.guesses(forWordRange: misspelledRange, in: lastWord!, language: "en_US")!
if guessedWord.count > 0 {
var i = 0
while (lastWord?.length)! > i {
textDocumentProxy.deleteBackward()
i += 1
}
self.textDocumentProxy.insertText(guessedWord[0])
}
}
}
self.textDocumentProxy.insertText(" ")
I had to make two changes to Rachits code. First to validate the currentString since it throws an exception if you press space bar twice. And second to check if the misspelled range is not 0 because that was also throwing an exception which I am yet to figure out why. But this works for me now as is.
Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon object contains words from various sources, including:
Unpaired first names and last names from the user’s Address Book database
Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list
A common words dictionary that includes the names of Apple products
In case anyone is still looking into this, I found a really nice C++ predictive text library called Presage. It seems to do a good job based on the demo but I'm having a lot of trouble trying to integrate it as a library (see my question here).
Let me know if anyone has any ideas, very interested in getting this working!
Actually, UILexicon is just a way to get some user-specific words that your spellchecking system should't try to fix. Probably, the most common way to use it is to fill out UITextChecker's list of ignored words.
let lexicon: UILexicon = ...
let checker: UITextChecker = ...
for entry in lexicon.entries {
if entry.documentText == entry.userInput {
checker.ignoreWord(entry.documentText)
}
}
Additionally, UILexicon can be used as source of autoreplaced shortcuts like ("omw" = "On my way!"), but it is not autocorrection in terms of spelling.
You can use below logic for AutoCorrect & it will also work in iOS 10
-(void)didClickAtAlphaNumericKeyboardKey:(NSString *)value {
if ([value isEqualToString:#" "]) {
UITextChecker *checker = [[UITextChecker alloc] init];
currentString = self.textDocumentProxy.documentContextBeforeInput;
NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray *components = [currentString componentsSeparatedByCharactersInSet:charSet];
NSString *lastWord = components.lastObject;
NSRange checkRange = NSMakeRange(0, lastWord.length);
NSRange misspelledRange = [checker rangeOfMisspelledWordInString:lastWord
range:checkRange
startingAt:checkRange.location
wrap:NO
language:#"en_US"];
NSArray *guessedWord = [checker guessesForWordRange:misspelledRange inString:lastWord language:#"en_US"];
if (guessedWord && guessedWord.count > 0) {
for (int i = 0; lastWord.length >i ; i++) {
[self.textDocumentProxy deleteBackward];
}
[self.textDocumentProxy insertText:[guessedWord objectAtIndex:0]];
}
}
[self.textDocumentProxy insertText:value];
}

Resources