Changing UIImage image property with the image name set in a dictionary - swift

I'm building a simple app which you click on a button and the image change randomly but I also want to add a label which describes the image so I created a dictionary contains the ["fileName":"Description"] but when I try changing the image I get an error:
"Cannot subscript a value of type '[String : String]' with an index of type 'Int'"
var randomNumber = 0
let arrayOfImages : [String:String] = ["ball1":"yes","ball2":"no","ball3":"ask again later","ball4":"the answer is yes","ball5":"i dont know"]
func rollButton() {
randomNumber = Int.random(in: 0...4)
ballImage.image = UIImage(named: arrayOfImages[randomNumber])
}
How can I change the UIImage.image using a Dictionary?

Replace
ballImage.image = UIImage(named: arrayOfImages[randomNumber])
with
ballImage.image = UIImage(named: Array(arrayOfImages.keys)[randomNumber])
As you can't subscript a dictionary it's for arrays , A good practice is to create
struct Item {
let imageName:String
let des:String
}
let arr = [Item(imageName: "ball1", des: "con1"),Item(imageName: "ball2", des: "con2"),Item(imageName: "ball3", des: "con3")]
let ran = arr[Int.random(in: 0...2)]
ballImage.image = ran.imageName

You are creating a list of [String: String], so you should access it using a key (String) and not a number (Int).
So you should correct this:
ballImage.image = UIImage(named: arrayOfImages["ball\(randomNumber)"])

Related

How to get some data out of an array in swift?

Here is my problem: I have an plist file, which have a simple strut:
root object is an array, and there are 2 sections in the array, each of them are dictionary including 2 pair key-value data:
and I'm going to create a tableView to show the datas, but I can't get the content out of the array :
here is how i declared my dataArray:
var plistArray = [AnyObject]()
can some one help me?
You need to properly cast at each level:
if let innerArray = plistArray[0] as? [AnyObject] {
if let dataDic = innerArray[indexPath.row] as? [String:String] {
if let imageName = dataDic["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}
}
}
But why are you using AnyObject when you know what the plist contains? Use proper types. You know it's an array of arrays of dictionaries with String keys and String values.
var plistArray = [[[String:String]]]()
Then all you need is:
if let imageName = plistArray[0][indexPath.row]["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}

OpenWeatherMap API SWIFT

So I am currently working on a personal project to help understand API's and how they work..so I am still a little new to iOS Development. I have already connected to the URL and gotten the data however now I am trying to make the results a little bit more clear cut.
Below is the code for the class (when the button is clicked it prints all this information)
First part of code
Second part of code
The error I get is Type 'Any' has no subscript members. Any idea as to why? Or how this can be fixed?
you can set their types like this then you can print values.
if let main = json["main"] as? [String: Any] {
let temp = main["temp"] as? Double
print("temp\(temp!)")
let temp_max = main["temp_max"] as? Double
print("temp\(temp_max!)")
let temp_min = main["temp_min"] as? Double
print("temp\(temp_min!)")
}
let items = json["weather"] as! [AnyObject]
let main = items[0]["main"] as! String
print(main)
let description = items[0]["description"] as! String
print(description)
let icon = items[0]["icon"] as! String
print(icon)
let name = json["name"] as! String
print("name\(name)")

Swift: Variable of Optional Dictionary inside Class: Shows Brackets in Output

I would like to make an Optional Dictionary Variable inside of a Class so that when I create an instance I don't HAVE to add that argument...
example
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0]){
}
}
var instance1 = Stuff(dictionary:["length":1.5])
var array: [Stuff] = [instance1, instance2]
let arraySet = (array[indexPath.row])
let X = arraySet.dictionary!
cell.Label.text = "\(X)"
This works but when i assign it to a cell.label.text the output shows Brackets...
"[length:1.5]"
How can i get rid of the brackets???
It's quite complicated to get rid of the brackets, because the key/value pair must be extracted out of the dictionary:
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0.0]){
self.dictionary = dictionary
}
}
let instance = Stuff(dictionary:["length":1.5])
if let dict = instance.dictionary where dict.count > 0 {
let key = dict.keys.first!
let value = dict[key]!
label.text = "\(key) : \(value)"
}
If you create the dictionary with non-optional literals, consider to declare the variable dictionary as non-optional

How to point a Json array to a local image?

I'm new at this so sorry if this is basic but I'm trying to use an array in a json file and have it point to an image in my asset library but I'm running into problems. Its written as:
[
{
"image":"shrew",
},
]
Is it wrong to write it as a string? Do I need to have specific code to translate the string into my image names?
Thanks for any help you can offer!
Edit:
The error I'm getting is on line
TrackPic.image = image
"Use of unresolved identifier 'TrackPic'"
class QuizModel: NSObject {
func getQuestions() -> [Question] {
// Array of question objects
var questions:[Question] = [Question]()
// Get Json array of dictionaries
let jsonObjects:[NSDictionary] = self.getLocalJsonFile()
// Loop through each dictionary and assign values to our question objs
var index:Int
for index = 0; index < jsonObjects.count; index++ {
// Current JSON dict
let jsonDictionary:NSDictionary = jsonObjects[index]
// Create a question obj
var q:Question = Question()
let imageName = jsonDictionary["image"] as! String
let image = UIImage(named: imageName)
TrackPic.image = image
// Assign the values of each key value pair to the question object
q.image = jsonDictionary["image"] as! String
q.questionText = jsonDictionary["question"] as! String
q.answers = jsonDictionary["answers"] as! [String]
q.correctAnswerIndex = jsonDictionary["correctIndex"] as! Int
q.module = jsonDictionary["module"] as! Int
q.lesson = jsonDictionary["lesson"] as! Int
q.feedback = jsonDictionary["feedback"] as! String
// Add the question to the question array
questions.append(q)
}
// Return list of question objects
return questions
}
you first need to get the image name from the json like you did
let imageName = jsonDictionary["image"] as! String
(If you want to be certain that you are parsing your JSON correctly, be sure to write the imageName to the console)
Then you need to initialise a UIImage with UIImage(named: String) with you image name from json so
let image = UIImage(named : imageName)
Then you have your image, and you can put this on an UIImageView.
I suppose in your case, this would be
q.image = image
IF q is a UIImageView

Does not have a member named 'subscript'

I'm building something and it all worked fine until Swift 1.2 came out. I made some changes but still have one line of code that is playing nice. I don't understand why this is breaking:
let swiftArray = positionDictionary.objectForKey["positions"] as? [AnyObject]
it gives me an error:
'(AnyObject) -> AnyObject?' does not have a member named 'subscript'
I also tried using this:
let swiftArray = positionDictionary.objectForKey?["positions"] as? [AnyObject]
but then I get an error saying:
Operand of postfix '?' should have an optional type; type is '(AnyObject) -> AnyObject?'
I'm really confused...can anyone help?
func addOrbsToForeground() {
let orbPlistPath = NSBundle.mainBundle().pathForResource("orbs", ofType: "plist")
let orbDataDictionary : NSDictionary? = NSDictionary(contentsOfFile: orbPlistPath!)
if let positionDictionary = orbDataDictionary {
let swiftArray = positionDictionary.objectForKey["positions"] as? [AnyObject]
let downcastedArray = swiftArray as? [NSArray]
for position in downcastedArray {
let orbNode = Orb(textureAtlas: textureAtlas)
let x = position.objectForKey("x") as CGFloat
let y = position.objectForKey("y") as CGFloat
orbNode.position = CGPointMake(x,y)
foregroundNode!.addChild(orbNode)
}
}
positionDictionary is an NSDictionary. You can use it just like a Swift dictionary - you don't need to use objectForKey.
You should just use if let and optional casting to get the value you want, which I think is an array of NSDictionary since you're using objectForKey again later:
if let downcastedArray = positionDictionary["positions"] as? [NSDictionary] {
for position in downcastedArray {
let orbNode = Orb(textureAtlas: textureAtlas)
let x = position["x"] as CGFloat
let y = position["y"] as CGFloat
orbNode.position = CGPointMake(x,y)
foregroundNode!.addChild(orbNode)
}
}
As a side note, CGPointMake is not stylistically preferred in Swift. Instead, consider using the CGPoint initializer:
orbNode.position = CGPoint(x: x, y: y)