Compile Time Error - arrays

let cell = UITableViewCell()
let dic = dict as Dictionary
let z = "Period \(String(Int(indexPath.row + 1)))" // something wrong with this
let x: Array = dic[z] as! Array
if (x[0] is String) {
cell.textLabel?.text = x[0] as? String
} else {
print("Error: it isnt a string")
}
tableView.reloadData()
return cell
What is wrong with this I feel like it is something simple but I just can't see it if you can see can you please help me! Thank you.
When I run this I get a segmentation fault and I have narrowed it down to this code. Again pls help. ;-;

Change the line to:
let z = "Period \(indexPath.row + 1)"
You don't need all of the casts. IndexPath.row is already an Int and there's no need to create a String from the Int.
You also have a few other serious issues. Assuming this code is in your cellForRowAt method, NEVER call reloadData() there. Just return a cell. Don't do anything else to the table in that method.
You should also properly dequeue a cell from the tableview. It will make your table view much more efficient.

Related

How can I tie independent values to strings in an array (Swift)?

So I'm practicing coding and I've set up an array of strings. What I want to happen is to have a function randomly select a string and if a certain string is selected, it would print out one message, and if any of the other strings are selected, it would print out a different one. I think setting up the messages could be done w/an if-else function, but I'm stuck on the earlier step of figuring out how to identify which string is called.
I did some searching and found this thread Get Random String from an Array and I copied the randomization code from it. I'm a bit overwhelmed with where to go from there.
What type of function/identifier etc would I need to set up so that the strings are uniquely identified?
class ViewController: UIViewController {
// Make collection of games and if Monsters is called, print "Take a break." If a diff string is called, print "Do your homework."
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
_ = games[randomNumber]
}
} // end of class
Your expectation is not very clear from your question, but I guess you are beginner and need a help with processing randomly selected string.
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
let randomlyPickedString = games[randomNumber]
if randomlyPickedString == "Cards Against Humanity" {
print("Print anything you want about Cards Against Humanity")
}
else if randomlyPickedString == "Mario Kart" {
print("Print anything you want about Mario Kart")
}
else if randomlyPickedString == "Halo" {
print("Print anything you want about Halo")
}
else {
print("Print anything you want about Pixeljunk Monsters")
}
}
If its a finite set of values in array, you can even decide to use switch

Randomly grab string from array, use as placeholder text, and equate to answer string in swift

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.

How to check if an variable of any type is an array

I tried to cast a swift protocol array as any array, but failed.
protocol SomeProtocol: class{
}
class SomeClass: NSObject, SomeProtocol{
}
let protocolArray: [SomeProtocol] = [SomeClass()]
let value: Any? = protocolArray
if let _ = value as? [SomeProtocol]{
print("type check successed") //could enter this line
}
Above code could work as expected.
However, my problem is, I have a lot of protocols, and I don't want to check them one by one. It is not friendly to add new protocol.
Is there any convenience way to do check if above "value" is a kind of array like below?
if let _ = value as? [Any]{
print("type check successed") //never enter here
}
edit:
Inspired by Rohit Parsana's answer, below code could work:
if let arrayType = value?.dynamicType{
let typeStr = "\(arrayType)"
if typeStr.contains("Array"){
print(typeStr)
}
}
But these code seems not safe enough, for example, you can declare a class named "abcArray".
Although we could use regular expression to check if "typeStr" matches "Array<*>", it seems too tricky.
Is there any better solution?
You can use reflection:
if value != nil {
let mirror = Mirror(reflecting: value!)
let isArray = (mirror.displayStyle == .Collection)
if isArray {
print("type check succeeded")
}
}
You can check the type of value using 'dynamicType', here is the sample code...
if "__NSCFArray" == "\(page.dynamicType)" || "__NSArrayM" == "\(page.dynamicType)"
{
print("This is array")
}
else
{
print("This is not array")
}

Populating an array using Parse queries (Swift)

I am trying to populate an array with a query from my parse database. When I try to print out the content of the array, I get an EXC_BAD_INSTRUCTION error. It doesn't seem like I'm properly appending new elements into my array, I'd appreciate any sort of tips
func loadSampleTasks() {
tasks = [Task]()
let query = PFQuery(className: "Task")
query.whereKey("TaskName", equalTo: "kenny")
query.findObjectsInBackgroundWithBlock() {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil && objects != nil {
self.parseResults(objects!)
print(self.tasks) // this prints out Kenny object as expected
}
}
print(tasks) // prints an empty array
}
func parseResults(objects: Array<PFObject>){
for object in objects { //looping through returned data
print("no error in Parse lookup")
let parseResult1 = Task(name: object["TaskName"] as! String)
parseResult1?.completed = object["Completed"] as! Bool
print("Parse result in object loop: \(parseResult1!.name)")
tasks.append(parseResult1!)
}
}
Any help much appreciated!
To what thefredelement said, "This is happening because you're getting your parse results in a closure, which means it may execute after the function itself has already returned." Before this happens, though, it won't work properly and you'll come back with that error.
I got it to work. I had to tableView.reloadData() within the closure. Thank you so much for the help!

swift array.removeAtIndex error

How come I'm getting the error "NSArray does not have a member named 'removeAtIndex'. How can I fix this? The error is on the fourth last line. Sorry if my question is stupid, I'm fairly new to programming. I appreciate all the help I get.
import Foundation
let userDefaults = NSUserDefaults.standardUserDefaults()
func isAppAlreadyLaunchedOnce()->Bool{
let defaults = NSUserDefaults.standardUserDefaults()
if let isAppAlreadyLaunchedOnce = defaults.stringForKey("isAppAlreadyLaunchedOnce"){
println("App already launched")
return true
}
else{
defaults.setBool(true, forKey: "isAppAlreadyLaunchedOnce")
println("App launched first time")
return false
}
}
struct newFactBook {
let factsArray = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built."]
}
var checkLaunch = isAppAlreadyLaunchedOnce()
var oldFunFactsArray = []
if(checkLaunch == false){
oldFunFactsArray = newFactBook().factsArray
}
else if (checkLaunch == true){
oldFunFactsArray = userDefaults.objectForKey("key") as! NSArray
}
func randomFacts1() -> (String, Int){
var unsignedArrayCount = UInt32(oldFunFactsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
var randomNumber = Int(unsignedRandomNumber)
return (oldFunFactsArray[randomNumber] as! String, randomNumber)
}
oldFunFactsArray.removeAtIndex[randomFacts1().1] //error here
userDefaults.setObject(oldFunFactsArray, forKey:"key")
userDefaults.synchronize()
println(oldFunFactsArray)
We have some problems here:
1 How to invoke a method
removeAtIndex is a method that accepts an Int as parameters. It cannot be invoked this way
removeAtIndex[randomFacts1().1]
instead you should write
removeAtIndex(randomFacts1().1)
2. The type of oldFunFactsArray is NSArray and it's wrong.
Intact when you write this:
var oldFunFactsArray = []
Swift does infer this:
var oldFunFactsArray : NSArray = []
But at this point you have an immutable NSArray so it does not have the removeAtIndex method.
Since you are using Swift I suggest you to declare the var oldFunFactsArray as follow:
var oldFunFactsArray : [String]
if checkLaunch == false {
oldFunFactsArray = newFactBook().factsArray
} else {
oldFunFactsArray = userDefaults.objectForKey("key") as! [String]
}
Please note that here I am declaring a Swift array of String(s). Since I use the var keyword this array will be mutable and we will be able to invoke removeAtIndex later on.
Also note that in the else branch I am force-casting the result of objectForKey to [String]. It will be fine since I see, below, you are writing the oldFunFactsArray in that slot.
Hope this helps.
You need to use NSMutableArray to use this method.
NSArray is not Mutable (can not change its content after it is intialized).

Resources