Swift hasSuffix method crashing app - ios

I'm trying to detect whether or not a user's input ends with a blank space, and if it does, to remove that space. I'm using the .hasSuffix() method to see if the space exists, and it should return a boolean variable that I can test for and determine the proper course of action. However, when I check whether the value is true or false, the app crashes. Any thoughts on why that might be? Here's the code:
var userGuess = userGuessField.text.lowercaseString
var guessEndsWithSpace: Bool = userGuess.hasSuffix(" ")
// The above will return true if the string ends with a space, so when this happens, remove the space and then check their guess
if (guessEndsWithSpace == true) {
println("Guess ends with a space")
// checkAnswer(userGuess)
} else {
println("Guess does not end with a space")
// Otherwise, just check their guess
// checkAnswer(userGuess)

Related

Get the current text inside of a textfield for IOS custom keyboard

I am developing a IOS custom keyboard. I was wondering if there was a way to fetch the current text inside of the text field and how it would work.
For example, we can use textDocumentProxy.hasText() to see if the textfield has text inside but I want to know the exact string that is inside the textfield.
The closest things would be textDocumentProxy.documentContextBeforeInput and textDocumentProxy.documentContextAfterInput. These will respect sentences and such, which means if the value is a paragraph, you will only get the current sentence. Users have been known to retrieve the entire string by repositioning the cursor multiple times until everything is retrieved.
Of course, you generally do not have to worry about this if the field expects a single value like a username, email, id number, etc. Combining the values of both before and after input contexts should suffice.
Sample Code
For the single phrase value, you would do:
let value = (textDocumentProxy.documentContextBeforeInput ?? "") + (textDocumentProxy.documentContextAfterInput ?? "")
For values that might contain sentence ending punctuation, it will be a little more complicated as you need to run it on a separate thread. Because of this, and the fact that you have to move the input cursor to get the full text, the cursor will visibly move. It is also unknown whether this will be accepted into the AppStore (after all, Apple probably did not add an easy way to get the full text on purpose in order to prevent official custom keyboards from invading a user's privacy).
Note: the below code is based off of this Stack Overflow answer except modified for Swift, removed unnecessary sleeps, uses strings with no custom categories, and uses a more efficient movement process.
func foo() {
dispatch_async(dispatch_queue_create("com.example.test", DISPATCH_QUEUE_SERIAL)) { () -> Void in
let string = self.fullDocumentContext()
}
}
func fullDocumentContext() {
let textDocumentProxy = self.textDocumentProxy
var before = textDocumentProxy.documentContextBeforeInput
var completePriorString = "";
// Grab everything before the cursor
while (before != nil && !before!.isEmpty) {
completePriorString = before! + completePriorString
let length = before!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
textDocumentProxy.adjustTextPositionByCharacterOffset(-length)
NSThread.sleepForTimeInterval(0.01)
before = textDocumentProxy.documentContextBeforeInput
}
// Move the cursor back to the original position
self.textDocumentProxy.adjustTextPositionByCharacterOffset(completePriorString.characters.count)
NSThread.sleepForTimeInterval(0.01)
var after = textDocumentProxy.documentContextAfterInput
var completeAfterString = "";
// Grab everything after the cursor
while (after != nil && !after!.isEmpty) {
completeAfterString += after!
let length = after!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
textDocumentProxy.adjustTextPositionByCharacterOffset(length)
NSThread.sleepForTimeInterval(0.01)
after = textDocumentProxy.documentContextAfterInput
}
// Go back to the original cursor position
self.textDocumentProxy.adjustTextPositionByCharacterOffset(-(completeAfterString.characters.count))
let completeString = completePriorString + completeAfterString
print(completeString)
return completeString
}

How to check for an undefined or null variable in Swift?

Here's my code:
var goBack: String!
if (goBack == "yes")
{
firstName.text = passFirstName1
lastName.text = passLastName1
}
All I want to do is execute the if-statement if 'goBack' is undefined. How can I do that? (I don't know what to put in the blank)
The overall program is more complicated which is why I need the variable to be undefined at first. In short, I'm declaring 'goBack', asking the user to type in their first and last name, then continuing to the next view controller. That view controller has a back button that brings us back to the first view controller (where I declared 'goBack'). When the back button is pressed, a 'goBack' string is also passed of "yes". I also passed the first and last name to the next view controller but now I want to pass it back. I'm able to pass it back, its just a matter of making the text appear.
EDIT: firstName and lastName are labels while passFirstName1 and passLastName1 are variables from the second view controller.
"All I want to do is execute the if-statement if 'goBack' is undefined. How can I do that?"
To check whether a variable equals nil you can use a pretty cool feature of Swift called an if-let statement:
if let goBackConst = goBack {
firstName.text = passFirstName1
lastName.text = passLastName1
}
It's essentially the logical equivalent of "Can we store goBack as a non-optional constant, i.e. can we "let" a constant = goBack? If so, perform the following action."
It's really interesting, you can define a variable as optional, which means it may or may not be defined, consider the following scenerio:
you want to find out if the app has been installed before...
let defaults = NSUserDefaults()
let testInstalled : String? = defaults.stringForKey("hasApplicationLaunchedBefore")
if defined(testInstalled) {
NSLog("app installed already")
NSLog("testAlreadyInstalled: \(testInstalled)")
defaults.removeObjectForKey("hasApplicationLaunchedBefore")
} else {
NSLog("no app")
defaults.setValue("true", forKey: "hasApplicationLaunchedBefore")
}
Then all you need to do is write a function to test for nil...
func defined(str : String?) -> Bool {
return str != nil
}
And you've got it. A simpler example might be the following:
if let test : String? = defaults.stringForKey("key") != nil {
// test is defined
} else {
// test is undefined
}
The exclamation mark at the end is to for unwrapping the optional, not to define the variable as optional or not
"All I want to do is execute the if-statement if 'goBack' is undefined"
The guard statement (new in Swift 2) allows exactly this. If goBack is nil then the else block runs and exits the method. If goBack is not nil then localGoBack is available to use following the guard statement.
var goBack:String?
func methodUsingGuard() {
guard let localGoBack = goBack else {
print("goBack is nil")
return
}
print("goBack has a value of \(localGoBack)")
}
methodUsingGuard()
From The Swift Programming Language (Swift 3.1):
Constants and variables created with optional binding in an if
statement are available only within the body of the if statement. In
contrast, the constants and variables created with a guard statement
are available in the lines of code that follow the guard statement, as
described in Early Exit.

iPhone string comparison strange issue in iOS 6

I used to compare the text entered in a txt field as below,
if ([myTextfield.text isEqualToString: #""])
{
// success code
}
else
{
// my code
}
in iOS 7 this check works perfectly. If nothing entered in to the text field, condition is success. But in iOS 6 if the field is blank, this condition always false and moves to the else block.
So i did like,
if (myTextfield.text.length == 0)
{
// success code
}
else
{
// my code
}
This works fine, and I just wanted to know what is wrong in my first method.
If myTextfield.text is nil, [myTextfield.text isEqualToString: #""] will fail because messaging nil returns nil (or 0, NO as appropriate).
In the second case you have, you are checking for == 0, so even if the string is nil you will still get a positive result.
In iOS7, untouched UITextFields return nil, whereas in previous iOS versions they return an empty string. Touched UITextFields in both cases should return an empty string.
(Did you ask the question in reverse mistaking iOS6 w 7? If not, I'd also make sure the text field is hooked up properly since a touched iOS7 text field could return an empty string while an unsynthesized iOS6 text field could return NULL since iOS6 is especially strict in this way.)

Type True/False in Umbraco

We want to implement a check box[Type : true/false] in an DocumemtType in Umbraco.
Our current Project necessity is:
an check box which will decide whether an image should be an link or popup
The code goes this way ...
var child= #Model;
if(child.GetProperty("popUp").Value.ToString() == "1")
{
// true means image will act as popup
}
else
{
// false means image will act as link
}
But the problem is an error is occurred "Cannot perform runtime binding on a null reference"
I have also tried code like ,
if (child.GetProperty("popup").Value.Equals("1"))
{
}
or
if (child.GetProperty("popup").Value.ToString().Equals("1"))
{
}
but still not able to get it. All suggestions are welcomed .
node.GetProperty("popUp") is the way to go. If your control value is actually string, then your check logic would look like
if (node.GetProperty<string>("popUp") == "1"){}
Effectively generic GetProperty is what your code does, but it handles the null case, returning default(string).
(I have never used the dynamic thing, in case something will go wrong there, do the typed var node = new Node(id);)
Since you recently added the property to the document type, unless each node of that type has been published, the property will return null. You'll need to check if the property is null first then check if its true.
var popUp = child.GetProperty("popUp");
if (popUp != null && popUp.Value.Equals("1"))
{
// popup...
}
else
{
// link...
}
Used the below code and it worked fine for me
var child= #Model;
if(#child.popUp)
{
// true means image will act as popup
}
else
{
// false means image will act as link
}
Use this:
var child= #Model;
if(child.GetPropertyValue<bool>("popUp", false))
{
// true means image will act as popup
}
else
{
// false means image will act as link
}

iOS Compare Value of Label

I'm using a label to display the string result of function. However I have a class variable that stores the previous result and I need to update that variable in different ways depending on different conditions. The code I wrote is
if(displayPassword.text == #"Memorable")
{
prevpass = [newPassword returnPassword];
}
else
{
prevpass = displayPassword.text;
}
However it always jumps to the else as it seems to show under debugging that displayPassword.text is always empty depsite it showing a value.
You can only use == to compare scalar values. A string is an object. You need to use the isEqual: or isEqualToString: method instead.
if([displayPassword.text isEqualToString:#"Memorable"]) {

Resources