I am using the standard method I think to check a word for validity. I have a 4 part array that is joined to make the word being verified.
I have this placed in my touches began func in a SpriteKit scene however it always gives me the answer "CORRECT SPELLING" even when it is not.
Curiously when I put the exact same bit of code into my did move to view func so it runs when the game starts it works perfectly well. The code is exactly the same except instead of the joined array I just create a let word = "WORD" before the code. So I am guessing the problem must be something to do with my joined array??
This is my code
let word = wordArray.joined()
let textChecker = UITextChecker()
let misspelledRange = textChecker.rangeOfMisspelledWord(
in: word, range: NSRange(0..<word.utf16.count), startingAt: 0, wrap: false, language: "en_US")
if misspelledRange.location != NSNotFound,
let guesses = textChecker.guesses(
forWordRange: misspelledRange, in: word, language: "en_US")
{
print("Guess: \(String(describing: guesses.first))") //Output is: Guess: Optional("Tester")
} else {
print("\(word) CORRECT SPELLING")
}
Turned out my issue was that UITextChecker does not like full caps!
Only accepts lower case spellings
Related
Forgive all my comments, I'm learning and that keeps me straight. Looking for a better solution to my conditional statement near the bottom and provided the rest for context. Tried out the loop comment suggested, but still not getting the right result as written here
// define the main package file
package main
//importing formatting features for the user I/O and string manipulation packages
//Parenthesis not needed if only importing 1 package
import (
"fmt"
"strings"
)
// defining the main function of the standalone app
func main() {
//initializing a string array
options := []string{"lemon", "orange", "strawberry", "banana", "grape"}
//creating a slice in the array to designate favorites
favFruits := options[0:3]
fmt.Println(options)
//initializing variable for user input
var fruit string
fmt.Print("Favorite Fruit Not Listed: ")
fmt.Scan(&fruit)
//convert response to lowercase
fruitConv := strings.ToLower(fruit)
//conditional statement example
for _, pick := range options {
if pick == fruitConv {
fmt.Println("You were supposed to pick something else")
break
} else {
fmt.Println("Response Accepted!")
break
}
break
}
//adding user inputed favorite fruit to the sliced array
favFruits = append(favFruits, fruitConv)
fmt.Print(favFruits)
}
I got your point. If you go to official Go packages section you will get slices package over there. Ref: slices
There is one function named contains inside the slices package, you can make use of that function. For your simplicity, I have created one example matching with your scenario.
func main() {
//initializing a string array
options := []string{"lemon", "orange", "strawberry", "banana", "grape"}
// assuming fruit as user input
fruit := "lemon"
//conditional statement example
if fruit == "coconut" || fruit == "coconuts" {
fmt.Println("Coconuts are nasty (except on your hair/skin)")
//**there has to be a way to simplify this code if the array grows server-side or something**
} else if slices.Contains(options, fruit) {
fmt.Println("You were supposed to pick something different...")
}
}
Here is the working link :- https://goplay.tools/snippet/bzSm_biR4Vr
Note: Since in your scenario there is lot of such contain checks, I would recommend to use map instead of slice. Internally if you deep dive in conatins function of slice you will get to know.
I have two UITextFields that get the placeHolder.text randomly from an array. The part I am stuck on, is having an element in an array of answers, correspond to the placeHolder text.
Meaning: placeHolder.text is a question, user text input is the answer, and we check that the user answer is the same as the hard coded value.
sample code:
let questionArray = ["name of your cat?", "name of your other cat?"]
let questionArray2 = { more stupid questions ]
let answerArray = ["cat damen", "diabetes"]
let answerArray2 = [ more stupid answers ]
var answerContainer: String()
var answerContainer2: String()
uitextField1.placeHolder = questionArray.randomElement()
uitextField2.placeHolder = questionArray2.randomElement()
Heres where I get stupid :
func answerGenerator {
if UItextField1.placeHolder == questionArray[0] {
answerContainer = answerArray[0]
}
}
func submit(_ sender: UIButton) {
if uitextField.text == answerContainer && uitextField2.text == answerContainer2 {
do good stuff
}
}
I tried using a dictionary, but got stuck. I also thought about an Enum / Switch Case, but also got stuck as I have two textFields that need the placeHolder generated randomly.
so what happens is the actual answer that's supposed to be allocated to its question, maybe it happens, but I'm not grabbing it correctly to compare what the user will type in the textfield.
Its so easy, but I'm overthinking this.
I have Swift code which reads a binary file representing a sequence of UInt32 values like this:
let fileData = binaryFile.readData(ofLength: 44)
guard fileData.count > 0 else { break }
let headerData = fileData.withUnsafeBytes {
Array(UnsafeBufferPointer<UInt32>(start: $0, count: 11))
}
let polyCount = headerData[1].bigEndian
let polyFlags = headerData[2].bigEndian
I'd not used the program containing this code for a while, but when returning to it recently, it still works as expected, but now gives a deprecation warning:
"withUnsafeBytes is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead"
I've searched for quite a long time for an un-deprecated way to do this without success. There are many examples across the web (including in stackoverflow) but almost all of them written before this deprecation into effect. Frankly, I've fried my brain hunting and trying suggestions! I am prepared to accept that I'm missing something totally obvious ("If it's getting complicated, you're doing it wrong."), but I work in an environment where I have no colleagues to ask .. except here.
Any guidance would be much appreciated.
RamsayCons's own solution is nice, but what about the performance? I think, it could be better if we reduce all unnecessary operation.
extension Data {
func toArray<T>(type: T.Type) -> [T] where T: ExpressibleByIntegerLiteral {
Array(unsafeUninitializedCapacity: self.count/MemoryLayout<T>.stride) { (buffer, i) in
i = copyBytes(to: buffer) / MemoryLayout<T>.stride
}
}
}
measured performance gain depends, but number of execution per second is at least doubled. Bigger the data, bigger advantage!
self.dataArray = data.withUnsafeBytes{ Array($0.bindMemory(to: UInt32.self))}
Well, letting some time pass restored brain function! I found an answer (in stackoverflow, of course):
round trip Swift number types to/from Data
some way into that question/answer is:
extension Data {
func toArray<T>(type: T.Type) -> [T] where T: ExpressibleByIntegerLiteral {
var array = Array<T>(repeating: 0, count: self.count/MemoryLayout<T>.stride)
_ = array.withUnsafeMutableBytes { copyBytes(to: $0) }
return array
}
}
The trick is that Arrays are not necessarily stored in contiguous memory so simply copying enough bytes in order to the destination doesn't do it. I hope this helps the next person hunting with a fried brain!!
I am trying to loop through an array of names to get the index of a certain string. I then want to set the index of my UIPicker to the said string.
I have the following code however this causes the app to crash due:
let index = self.nameArray.index(where: {$0 == assetArray[0].Owner })
scroll_owners.selectRow(index ?? 0, inComponent: 0, animated: true)
When debugging the index is getting a value of index 6176573120 which of course isn't in the range of my UIPicker so causes the crash.
Any ideas on why this may be happening?
Using the suggested answer throws the following error:
unrecognized selector sent to instance 0x101134af0'
There is definitely a match in assetArray[0] with the name that is being passed through.
Doing a bit more investigation trying to run the following line of code alone gives the same error:
scroll_owners.selectRow(0, inComponent: 0, animated: true)
Does this mean I'm missing a delegate method?
Asset Array and Name Array:
var assetArray : [Asset] = []
var nameArray = [String]()
EDIT:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
self.scroll_owners.delegate = self
self.scroll_owners.dataSource = self
I've tried to get this working another way - I know this is an ugly way of doing it I'm just trying to see why the accepted swift way isn't working:
var i : Int = 0
while (nameArray[i] != name)
{
print(nameArray[i])
i=i+1
}
scroll_owners.selectRow(i, inComponent: 0, animated: true)
This section of code crashes and the while loops is never entered due to the index being out of bounds - does this mean the issue could be with nameArray?
i think the problem is that .index doesn't return an IndexPath.
But selectRow needs an indexPath as parameter.
.index
.selectRow
I have managed to solve this error myself in a slightly different way.
In my function which populates the nameArray and the UIPicker I have placed the following code:
var i : Int = 0
while (self.nameArray[i] != name)
{
print(self.nameArray[i])
i=i+1
}
self.scroll_owners.selectRow(i, inComponent: 0, animated: true)
The reason the code was crashing was due to the fact that the nameArray was not finishing being populated before I was trying to do the comparisons. I know this may not be the accepted swift way of doing this but it works.
The issues were caused due to the function being run on a seperate thread I believe.
I am facing the problem that I fill up an array with data and when I want to remove it later, even though I call the removeAll() the array still is not empty.
Better see my code for a more clear view on the problem
Updated new code
#objc func textFieldDidChange() {
doSearch()
if let commentText = commentTextField.text , !commentText.isEmpty {
sendButton.setTitleColor(UIColor.blue, for: UIControlState.normal)
sendButton.isEnabled = true
return
}
sendButton.setTitleColor(UIColor.lightGray, for: UIControlState.normal)
sendButton.isEnabled = false
}
func doSearch() {
let caption = commentTextField.text
let words = caption?.components(separatedBy: CharacterSet.whitespacesAndNewlines)
self.usersSuggestion.removeAll()
for var word in words! {
self.usersSuggestion.removeAll()
if word.hasPrefix("#") {
word = word.trimmingCharacters(in: CharacterSet.punctuationCharacters)
self.isCellSelected = true
self.usersSuggestion.removeAll()
API.User.suggestUsers(withText: word, completion: { (user) in
print("closure", word)
self.usersSuggestion.append(user)
self.tableView.reloadData()
print("#", self.usersSuggestion.count)
})
self.usersSuggestion.removeAll()
tableView.reloadData()
} else {
self.isCellSelected = false
self.usersSuggestion.removeAll()
tableView.reloadData()
}
self.usersSuggestion.removeAll()
tableView.reloadData()
}
}
I am facing the problem here that the array, even though I call multiple times the removeAll() method, never gets back to 0. When I have 2 user, link one, the next time I write an # I get the 2 users+ the linked user (so him twice). I can do it infinitely, having like 100 userSuggestions with just 2 existing users.
photos
You are printing the count immediately after inserting an element in the array. This will alway give a count of 1.
// count was zero
self.hashTags.insert(hashTag, at: 0) // adding one
print("# = ", self.hashTags.count) // count is now 1
Given that the API.user... function uses a completion handler, I would assume that this happens in a separate thread or at least asynchronously so you could event get into situations where the UI shows empty and suddenly shows one.
You may want to structure your code differently to better convey the separation between requesting data and displaying the (asynchronously obtained) results. Embedded completion handlers tend be misleading and give the impression that execution will happen in their visually organized sequence.