Swift: iterating through plist - ios

I am trying to use a plist to hold an array of dictionaries. Everything seems to be ok except for when I try to iterate through each element of the array. In this case I an using NSArrays and NSDictionarys.
In the below example, albumInfo is a NSDictionary. The key, "Title" is linked with the a string object. I am using a method called addAlbumInfo which has arguments which are all Strings except for the "price:"
Please help.
var pathToAlbumsPlist:NSString = NSBundle.mainBundle().pathForResource("AlbumArray", ofType: "plist");
var defaultAlbumPlist:NSArray = NSArray(contentsOfFile: pathToAlbumsPlist);
for albumInfo:NSDictionary in defaultAlbumPlist {
self.addAlbumWithTitle(
albumInfo["title"], //Says it is not convertable to a string
artist: albumInfo["artist"],
summary: albumInfo["summary"],
price: albumInfo["price"].floatValue,
locationInStore: albumInfo["locationInStore"]
);
}

Since albumInfo is an NSDictionary it can only contain AnyObjects, which means it can't contain a Swift String that is a struct. If your addAlbumWithTitle expects a String and you try to pass it an AnyObject it will give you this error. You can cast albumInfo["title"] to a Swift String like this:
albumInfo["title"] as String

the solution I found was to make albumInfo assume a type and then type case each of the values
var pathToAlbumsPlist:NSString = NSBundle.mainBundle().pathForResource("AlbumArray", ofType: "plist");
var defaultAlbumPlist:NSArray = NSArray(contentsOfFile: pathToAlbumsPlist);
for albumInfo in defaultAlbumPlist {
self.addAlbumWithTitle(albumInfo["title"] as String,
artist:albumInfo["artist"] as String,
summary:albumInfo["summary"] as String,
price:albumInfo["price"] as Float,
locationInStore:albumInfo["locationInStore"] as String
);
}

Related

How can I access an struct attribute from an array?

What I want to do is to, after storing several objects of type CodigosAutorizacion inside an array:
for value in 0..<(array.count) {
let codeArray = CodigosAutorizacion(
code: validateData!["codigo"] as? String,
codeCancel: validateData!["cancela_codigo"] as? String,
codeSite: validateData!["cod_sitio"] as? String,
codeSiteCancel: validateData!["cancela_cod_sitio"] as? String,
instance: validateData!["instancia"] as? String
)
codes.append(codeArray)
}
Access the object attributes from the array like this:
codeCell.codigoSitio.text = codes[indexPath.row].instance
This piece throws me the next errors
-No exact matches in call to subscript
-Reference to member 'instancia' cannot be resolved without a contextual type
this is because ´codes´ is an array and not a CodigosAutorizacion type
Storing these objects in an array is important because I will need to generate a table with several of this CodigosAutorizacion objects. Is there any way this can be possible?
var codes = [CodigosAutorizacion]()
for value in 0..<(array.count) {
let codeArray = CodigosAutorizacion(
code: validateData!["codigo"] as? String,
codeCancel: validateData!["cancela_codigo"] as? String,
codeSite: validateData!["cod_sitio"] as? String,
codeSiteCancel: validateData!["cancela_cod_sitio"] as? String,
instance: validateData!["instancia"] as? String
)
codes.append(codeArray)
}
-- Try this --
Fixed! it was a problem with the codes array declaration, it was not supposed to be var codes: Array<Any> but instead var codes: Array<CodigosAutorizacion> in order to access CodigosAutorizacion's properties

iOS Swift 3 - Argument labels '(of:)' do not match any available overloads Error

I'm getting the error message Argument labels '(of:)' do not match any available overloads. Below is the code I'm using.
let prefs = UserDefaults.standard
var id: String!
if var array = prefs.string(forKey: "myArray"){
if let index = array.index(of: id) {
array.remove(at: index)
prefs.setValue(array, forKey: "myArray")
}
}
I've seen a lot of answers on Stack Overflow with very similar code to that. So I'm not quite sure why this wouldn't be working.
Basically I'm just trying to remove the element in the array that = id then set that new array to the user defaults.
Update
Just updated the code above to show how array is getting defined. id is a string that is defined in a separate section.
By accessing prefs.string(forKey: "myArray"), you are getting a String, not an array of strings. You should use this:
if var prefs.array(forKey: "myArray") as? [String] { }
or
if var prefs.value(forKey: "myArray") as? [String] { }
Make sure to not forget putting as! [String], because the first method returns [Any], an which can contain objects of any type, not specifically String. Then your error should be solved, because index(of: ) can only be used on Arrays of specified types.
Hope it helps!
Just make an alt + Click on an "array" variable to make sure it is of type Array ([String]), not a String. To apply .index(of:) method it must be an array.
Like this:
String does not have a method .index(of:). That's what the error is pointing at. And sure make a cast to [String]? if it fits.

Can't get dictionary item by index - cannot subscript String with an Int

I have a dictionary where key is string and value is array of strings.
var someItems : [String: [String]] = [String: [String]]()
I am trying to get item by it's index...
var temp = someItems[0]
But I am gettings error:
'subscript' is unavailable: cannot subscript String with an Int
I don't understand why this doesn't work?
Dictionary is key based not index based and the key is declared as String
var temp = someItems["key"]
Dictionary items are not sorted and therefore you can't call them with index. You should be able to access its value by writing someItems ["theString"], where theString is the selected key.
try this
if let array = someItems["your key for array"] as NSArray{
print(array)
}
it will return your array for the entered key

Swift - Dictionary with array of tuples

I am trying to create a list to hold the data for a tableview with sections.
I would like to use it like that:
cell.NameLabel.text = list[indexPath.section][indexPath.row].name
Edited
I tried to make the question simple because english is not my main language.
let me try to ask the right question:
I would like to create a dictionary with array of tuples
Something like that:
var myDict = Dictionary<Array<(code: String, type: String)>>()
And I would like to access like that:
myDict["blue"][0].type
The declaration of myDict in your example is wrong, because a Dictionary requires the type of the keys and the type of the values. You should declare it as:
var myDic = Dictionary<String, Array<(code: String, type: String)>>()
Then, you can use it (almost) as you wanted to:
myDic["one"] = [(code: "a", type: "b")]
myDic["two"] = [(code: "c", type: "d"), (code: "e", type: "f")]
let t = myDic["two"]![0].type
...
Note the ! after the myDic["two"]. Thats because accessing a Dictionary by key returns an Optional, you need to unwrap it first.
Actually, this code would be better:
if let item: Array<(code: String, type: String)> = myDic["two"] {
let t = item[0].type
...
}
Well, this would be a very simple Array of Array of an object. I invite you to read the Apple Language Reference of Swift about collections and Arrays :
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html
import UIKit
class Object {
var name: String
init(string: String) {
name = string
}
}
var objects: [[Object]] = [[Object]]()
for section in 0..<3 {
for i in 0..<10 {
objects[section][i] = Object(string: "My Object \(section) \(i)")
}
}
let myString = objects[2][1].name

Create an array in swift

I'm searching really much, but maybe I can't understand the results.
I found only that a array in SWIFT have as index int-values
var myArray = [String]()
myArray.append("bla")
myArray.append("blub")
println(myArray[0]) // -> print the result bla
But I will add a String with an String as index-key
var myArray = [String:String]()
myArray.append("Comment1":"bla")
myArray.append("Comment2":"blub")
println(myArray["Comment1"]) // -> should print the result bla
How should i declare the array and how I can append a value then to this array?
Your second example is dictionary
myArray["key"] = "value"
If you want array of dictionaries you would have to declare it like this
var myArray: [[String: String]]
Your first example is an array. Your second example is a dictionary.
For a dictionary you use key value pairing...
myArray["Comment1"] = "Blah"
You use the same to fetch values...
let value = myArray["Comment1"]
println(value)
You got the concept of array in the first example but for the second one you need a dictionary as they operate on key value pair
// the first String denotes the key while the other denotes the value
var myDictionary :[String:String] = ["username":"NSDumb"]
let value = myDictionary["username"]!;
println(value)
Quick reference for dictionaries collection type can be found here

Resources