iOS Copy Paste phone from contacts to UITextField adds strange unicode characters - ios

The simplified scenario is the following.
New project using Single View App template.
Add a UITextField to the ViewController.
Run the app and copy and paste a Contacts phone number [ej. John Appleseed one (888) 555-5512) ] to the UITextField.
The number will be added with a Unicode character at the beginning and at the end, getting like \u{e2}(888) 555-5512\u{e2} when exploring the variable while debugging.
This is really weird and in my opinion, not the intended behaviour.
Is this a bug or something that works intentionally this way?
Code:
Nothing complicated here. As described before, brand new project, add UITextField, add Button, and if button triggered print the result.
The print will show the phone just fine, just put a breakpoint in the print line and see the value of the phone var to see what I mean.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var phoneLabel: UITextField!
#IBAction func goButton(_ sender: UIButton) {
let text = phoneLabel.text ?? ""
print(text)
}
}
Tested in:
iOS 11.1 - iPhone X
Xcode 9.1
Steps with images:
This is what I got at the breakpoint line.

I had exactly the same issue recently. Interestingly enough what you see in the debugger is unfortunately not what is actually pasted.
If you copy the number to a different place and investigate it with your console for example you will get the following output:
>>> u"\U+202D(888) 5555-5512\U+202C"
u'\u202d(888) 5555-5512\u202c'
>>> name(u"\U+202D")
'LEFT-TO-RIGHT OVERRIDE'
>>> name(u"\U+202C")
'POP DIRECTIONAL FORMATTING'
So as you can see it is really two different invisible characters controlling the flow of the text.
In order to solve that I filtered out all unicode characters of the cF category. So you could do:
phoneLabel.text?.replacingOccurrences(of: "\\p{Cf}", with: "", options: .regularExpression)

Related

XCTest typeText cant switch keyboard to another language

Heloo!
I am working with uitests on iOS and am using typeText method to enter a string into a textField. The application is multilingual, so the test case involves entering a string in different languages. However, the method fails for strings other than the current keyboard language (cannot switch the keyboard language to enter this string, although the simulator has a keyboard with this language).
I haven't been able to solve this problem for a week now. I did not find ways to switch the keyboard language for typeText, or otherwise solve the problem.
Please, help!
UPD (for drunkencheetah):
I use this method as XCUIElement extension:
func clearAndTypeText(_ text: String) {
let typedText = self.value as? String
focusIfNeeded()
if typedText != nil {
let deleteText = String(repeating: XCUIKeyboardKey.delete.rawValue, count: typedText!.count)
typeText(deleteText)
}
typeText(text)
}
firstTextField.clearAndTypeText("English12345") // Result - "English12345"
secontTextField.clearAndTypeText("文本123") // Chinese as example. Result -> "123"
// This will take a very long time to print.
If I manage to manually switch the keyboard language (while running the test) from English to Chinese, the text will be printed. Otherwise, only numbers
typeText() should function regardless of the current keyboard language. I've just tested typing text in Bulgarian(Cyrillic) and Chinese without issues.
Since your application is multilingual you should make sure you are locating the element respective to the current application language(if not using an accessibility identifier).
Also make sure the element has keyboard focus - use tap() on it before attempting typeText() just in case.
Make sure if running on simulator that I/O > Keyboard > Connect hardware keyboard is disabled
As Mike Collins suggests in the comments you could use the pasteboard (only on simulator!) like this:
UIPasteboard.general.string = "teststring"
textElement.doubleTap()
app.menuItems["Paste"].tap()
Note that this will not work on real devices.

Jetpack Compose TextField weird behavior when deleting text

This video explains better, please watch: Video
The code is very simple:
#Composable
fun Main() {
var note by remember {
mutableStateOf(
LoremIpsum(40).values.first() //generate a random string that contains 40 words
)
}
TextField(value = note, onValueChange = { note = it })
}
I have tried pasting random strings and deleting them fast enough in a messaging app, to make sure that this problem does not cause by the soft keyboard/Google keyboard, and it's just working fine in the messaging app.
I don't understand why this could happen, could this be a bug with TextField?
You can download the project here, but basically, all the code has been posted above.

How to check if the phone number is chosen from the suggestion in IOS?

I want to check if the phone number entered in the textfield is from the suggestion or not as soon as it is entered so that i could remove the code from the phone number. how can we do that?
using these library and functions
Import ContactUI
Import UIKit
#IBAction func getcontact(_ sender : AnyObject) {
}
and you can even say the contact using this
IBAction func SayContact (_ sender : AnyObject) {}
you may refer to this book
it explain how to do that in details
when you open the link scroll down little , until you find the code where it talk about Func ShowPEoplePicker ( )
and you will get it done :)
click here to open the book
Good luck

iOS 8.1 Swift Dictionary Error: EXC_BAD_ACCESS (XCode 6.1)

TLDR: I'm getting an EXC_BAD_ACCESS error using swift in XCode 6.1 building for iOS8.1. I believe the issue is likely a compiler error.
I am making an app wherein the user is allowed to add (Korean) words from a dictionary (in the English sense) to a word list. I have the following classes that define a word (with associated definitions, audio files, user-interaction statistics, etc.) and a word list (with an associated list of words and methods to add/remove words to the list, alphabetize the list, etc):
class Word: NSObject, NSCoding, Printable {
var hangul = String("")
var definition = String("")
// ...
}
class WordList: NSObject, NSCoding {
var title = ""
var knownWords = Dictionary<String,String> ()
// ...
func addWordToList(wordName: String, wordDefinition: String) {
// Debug statements
println("I am WordList \"\(self.title)\" and have the following knownWords (\(self.knownWords.count) words total): ")
for (_wordName,_wordDefinition) in self.knownWords {
println("\t\"\(_wordName)\" : \(_wordDefinition)")
}
println("\nI am about to attempt to add the word \"\(wordName)\" with definition \"\(wordDefinition)\" to the above dictionary")
// Add word to wordList, including the 'let' fix
fix_EXC_BAD_ACCESS_bug()
knownWords[wordName] = wordDefinition // EXC_BAD_ACCESS
}
func fix_EXC_BAD_ACCESS_bug() {
// This empty line attempts to solve a exc_bad_access compiler bug when adding a new value to a WordList dictionary
let newDic = self.knownWords
}
// ...
}
Next I have a UITableViewController with a UISearchBar that I use to display the dictionary (again in the English sense) of words to the user. The user adds words by tapping a button (which is displaying an image) on the right of each cell, which calls the #IBAction func addWord() in the viewController:
class AddingWordsToWordList_TableViewController: UITableViewController, UISearchResultsUpdating {
var koreanDictionary = KoreanDictionary() // Custom class with method 'getWord(index: Int)' to return desired Word
var filteredSearch = [Word]()
// ...
// Add word
#IBAction func addWord(sender: UIButton) {
// Add word
if self.resultSearchController.active {
let word = filteredSearch[sender.tag]
wordList.addWordToList(word.hangul, definition: word.definition) // Enter addWordToList() here
} else {
let word = koreanDictionary.getWord(sender.tag)
wordList.addWordToList(word.hangul, definition: word.definition)
}
// Set image to gray
sender.imageView?.image = UIImage(named: "add133 gray")
// Save results
wordList.save()
// Reload table data
tableView.reloadData()
}
// ...
At first the app compiles and seems to run fine. I can add a new word list and start adding words to it, until I add the 8th word. I (always on the 8th word) get a EXC_BAD_ACCESS error in (WordList) addWordToList with the following println information:
I am WordList "School" and have the following knownWords (7 words total):
"방학" : school vacation
"대학원" : graduate school
"학년" : school year
"고등학생" : high school student
"초등학교" : elementary school
"학생" : student
"학교" : school
I am about to attempt to add the word "대학생" with definition "college student" to the above dictionary
Note that the order in which I add the words appears irrelevant (i.e. the word "college student" can be added successfully if it is one of the first 7 words). There is nowhere in the code where I explicitly change behavior based on the number of words in a word list (except to display the words in a word list as cells in a UITableView), or any dependencies that would (to my knowledge) make the 8th word a special number. And indeed this number can change by using the let hack= solution (see below) to a different number, but for a particular build is always the same number.
At this point I'm at a complete loss of what to do. I'm relatively new to swift and have spent quite a few hours looking up how to fix exc_bad_access errors. I've come to the following point:
It seems exc_bad_access errors usually mean one of three things (http://www.touch-code-magazine.com/how-to-debug-exc_bad_access/)
An object is not initialized
An object is already released
Something else that is not very likely to happen
I don't feel like either 1 or 2 can be the case for me, as right before we get the access error we can print out the contents of the dictionary in question (knownWords). However, as is always the case it is highly likely I'm missing something obvious, so please let me know if this is indeed true.
If the error is caused by 3 above ("something else") I have tried the following:
(From EXC_BAD_ACCESS on iOS 8.1 with Dictionary and EXC_BAD_ACCESS when updating Swift dictionary after using it for evaluate NSExpression solutions)
I have tried different variations of the let stupidHack = scenario, and it does sometimes change the results, but only the number of entries allowed before crashing (i.e. I can sometimes get to the ~15th/16th entry in the dictionary before the error). I have not been able to find an actual, bug-free solution using this method, however.
I have rebuilt using both Release and Debug modes; the error appears in both. Note I am only using the simulator and do not have a developer's license to try it on an actual device.
I have turned off (set to "None") compiler optimization (it was already off for the Debug build anyway).
I have tried building to iOS 8.0 with the same error results.
Any way to get around this issue is appreciated. A let hack = solution is acceptable, but preferably a solution will at least guarantee to not produce the error in the future under different build conditions.
Thanks!

UIAutomation with Instruments - How to tap copy/paste buttons?

I'm using Instruments for iOS automation and I can't seem to figure out how to tap options on the copy/paste menu. When I do a logElementTree(),I see that we are returning a UIEditingMenu and then three elements (which correspond to options of that menu, such as copy/paste, etc..). I am attempting to place this into a variable, and then trying to "tap" that variable but I cannot get that to work. Here is a sample of my code:
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
//This generates the highlighted text
app.dragInsideWithOptions({startOffset:{x:0.45, y:0.6}, endOffset:{x:0.45, y:0.6}, duration:1.5});
var copy = app.editingMenu.elements.withName("copyButton");
copy.tap();
Instruments returns, "0) UIAElementNil". In addition to the above, I've also tried:
app.elements.withName("copyButton")
window.elements.withName("copyButton")
So, I can get the editingMenu to produce the available options, but I cannot figure out a way to tap or select one of those options. I'm not quite sure I know how to reference those options to begin with.
Does anyone have any ideas?
Thanks!
You should try app.editingMenu().elements()[index].tap() where index is the index of the option you want to tap from the array of elements returned. I got my one working this way.
Hey.
First of all, I was always using .elements() not .elements... but it is JS, so it may be invoking function that is assigned to object property..?
Anyway, maybe this edit menu is not internal window of the app, but it is system level menu, that is invoked, when you do the drag? If that is true, try:
UIATarget.localTarget().frontMostApp().elements().withName("copyButton").tap();
But as I see in apple reference your version with calling app.editingMenu() should be fine...
Maybe try calling buttons by position, and you will see which respond:
UIATarget.localTarget().frontMostApp().editingMenu().elements()[0].tap;
UIATarget.localTarget().frontMostApp().editingMenu().elements()[1].tap;
UIATarget.localTarget().frontMostApp().editingMenu().elements()[2].tap;
You should find position of correct one this way. When you have it's position you can check its properties by button.logElement();. With this inf you you should be able to switch back to .withName method instead hardcoded position.
I did this similar to yoosiba but with editingMenu element names.
Using Xcode 4.5.1 and device running iOS 6.
Using Alex Vollmer's excellent tuneup_js for target, app and vtap().
Otherwise you can use UIATarget.localTarget().frontMostApp() and tap().
NOTE: vtap() will delay and retry tapping. Without this you may need to add your own delays.
// tap in textFieldA to see editingMenu.
app.mainWindow().textFields()["textFieldA"].vtap();
app.editingMenu().elements()["Select All"].vtap();
app.editingMenu().elements()["Copy"].vtap();
// must delay before attempting next tap
target.delay(2);
// ... navigate to different section of the app
// tap in textFieldB to see editingMenu.
app.mainWindow().textFields()["textFieldB"].vtap();
// paste clipboard contents copied from textFieldA into textFieldB
app.editingMenu().elements()["Paste"].vtap();
target.delay(2);

Resources