Changing value in Dictionary in a Array in UserDefaults - ios

I have a problem changing the value of a Dictionary in a Array
var array = (defaults.array(forKey: "Transactions")! as! [Dictionary<String, Any>])
(array.reversed()[index]["Title"] as! String) = titleTextField.text! // Cannot assign to immutable expression of type 'String'
Cannot assign to immutable expression of type 'String'
This is the error I get back
Is there a solution to this problem?

As Joakim points out, array.reversed() returns an immutable array.
Try this:
guard
var array = (defaults.array(forKey: "Transactions")! as? [Dictionary<String, Any>]),
let newText = titletextfield.text,
array[array.count-index]["Title"] = newText
(And then re-save your array to UserDefaults)

One more step will work
if var array = UserDefaults.standard.array(forKey: "Transactions") as? [Dictionary<String, Any>], let valueText = titleTextField.text {
array.reverse()
array[index]["Title"] = valueText
}

Related

Can't return elements from two-dimensional array

I'm trying to make a feature that saves a title and link to a website
This is what I am attempting to store
[0] -> [TITLE, LINK]
[1] -> [TITLE, LINK]
[2] -> [TITLE, LINK]
This is how I am doing it
//Create array
var favoriteProducts = [[String:String]]()
//Add products
let firstArray = [titleName:String(), link:String()]
favoriteProducts.append(firstArray)
//Add to defaults
UserDefaults.standard.set(favoriteProducts, forKey: "favProducts")
The next step is to loop through using ForEach to return the title and link. For debugging I'm trying to use
UserDefaults.standard.array(forKey: "favProducts")![0][0]
Which returns
Value of type 'Any' has no subscripts
However
UserDefaults.standard.array(forKey: "favProducts")![0]
Returns
(website, link)
So my question here is how do I return both the website and link individually and not just the entire subscript?
you can store arrayOfStrings In struct array and can access the vale from struct ,Say example
var favouriteProducts = [[String:Any]]()
var listOfSite = [SiteDetail]()
var firstArray = ["titleName":"String","link":"firstlink"]
var secondArray = ["titleName":"s","link":"s"]
favouriteProducts.append(firstArray)
favouriteProducts.append(secondArray)
UserDefaults.standard.set(favouriteProducts, forKey: "favProducts")
let value = UserDefaults.standard.array(forKey: "favProducts") as? [[String:String]] ?? [[:]]
for values in value{
let siteName = values["titleName"] as? String ?? ""
let link = values["link"] as? String ?? ""
let siteDetail = SiteDetail(website: siteName, link: link)
listOfSite.append(siteDetail)
}
print("listOf \(listOfSite[0].link)")
print("listOf \(listOfSite[0].website)")
//////////////////////////
struct SiteDetail{
var website:String?
var link:String?
}
Here UserDefaults.standard.array returns an array of Any type and you are storing an array of the dictionary. So at the time of retrieve, you need to cast the array element as a dictionary.
Also, you can use the key to get the dictionary value.
let firstElement = (UserDefaults.standard.array(forKey: "favProducts")?[0] as? [String: String])
let title = firstElement?["titleName"]
let link = firstElement?["link"]

Extract vaues from an array in swift

I'm getting values of string in my response to whom i'm storing in an array. Its is storing properly.Now i want to get that values out of my array because later i have to add that in an another string to get their sum. My array looks like this, [0.5,0.5,0.5]. I have to extract all the 0.5 values and add them. I have tried a code it extract the values but in result it shows 0 value. My code is this,
let itemprice = UserDefaults.standard.string(forKey: "itemPrice")
print(itemprice)
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "addonPrice") as? [Int] ?? [Int]()
print(array)
let resultant = array.reduce(0, +)
print(resultant)
let result = itemprice! + String(resultant)
print(result)
i'm trying to add the arrays value to another value with the name itemprice. How can i get out all the values from my array and add them. The values in the array varies different time.
You are getting 0 as a result of let resultant = array.reduce(0, +) because in
let array = defaults.array(forKey: "addonPrice") as? [Int] ?? [Int]()
either the value stored in the defaults is an empty array, or the cast as? [Int] fails.
Considering you claim that the array is supposed to hold values [0.5,0.5,0.5] I assume that it is the latter case. [0.5,0.5,0.5] is an array of Double values, not Int values.
Try to fix it this way:
let array = defaults.array(forKey: "addonPrice") as? [Double] ?? [Double]()
UPDATE
From comments it seems that you are using strings everywhere, so then:
let itemprice = UserDefaults.standard.string(forKey: "itemPrice")
print(itemprice)
let defaults = UserDefaults.standard
// take it as an array of strings
let array = defaults.array(forKey: "addonPrice") as? [String] ?? [String]()
print(array)
// convert strings to Double
let resultant = array.map { Double($0)! }.reduce(0, +)
print(resultant)
let result = Double(itemprice!)! + resultant
print(result)
Although I would strongly recommend you to work with Double from the beginning (both to store it and use it).

How to save and retrieve Array of Objects value from Dictionary in Swift iOS?

I am newly to Swift programming. I am developing an app where I have an array of Objects that I need to save it into one Dictionary, means for Dictionary 'Array of Objects' should be my Value and 'ID' should be my Key.
Here 2 elements contains in my Array, how can I save and retrieve from Dictionary using any unique Key. Please suggest me. Thank you!
You can do it by
var myDict = Dictionary<String, Any>()
myDict = ["myKey": myArrayObjectName as! VideoRangeInfo]
Now you can access you array by use "myKey" of dictionary like below,
print("My array = \(myDict["myKey"] as! VideoRangeInfo)")
UPDATED: I think your array is objective c NSMutableArray not swift Array so
var myDic = NSMutableDictionary()
myDic.setObject(myArrayObjectName, forKey: "myKey")
And
print("My array = \(myDic.object(forKey: "MyKey") as! VideoRangeInfo)")
One simple approach is:
struct VideoRangeInfo {
var name: String
}
var arrayVideoRange = [
VideoRangeInfo(name: "Name1"),
VideoRangeInfo(name: "Name2"),
VideoRangeInfo(name: "Name3")
]
var dictionary = [String: VideoRangeInfo]()
for obj in arrayVideoRange {
dictionary.updateValue(obj, forKey: obj.name)
}
print(dictionary["Name1"]!)
print(dictionary["Name2"]!)
print(dictionary["Name3"]!)
Saving
var dictionary = Int:String
dictionary.updateValue(value: self.arrangeVideoInfo[0]!, forKey: 1)
dictionary.updateValue(value: self.arrangeVideoInfo[0]!, forKey: 2)
Getting
let value1 = dictionary[1] as! VideoRangeInfo
let value2 = dictionary[2] as! VideoRangeInfo

Cannot convert value of type `[String: String?]` to expected argument type `[String: String!]`

Hi i am getting error while appending value to dictornary. I am using Xcode 7 and Swift 2.
Error Message: Cannot convert value of type [String: String?] to expected argument type [String: String!]
Declaration:
var arrVoiceLanguages: [Dictionary<String, String!>] = []
following is my function
for voice in AVSpeechSynthesisVoice.speechVoices() {
let voiceLanguageCode = (voice as AVSpeechSynthesisVoice).language
let languageName = NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: voiceLanguageCode)
let dictionary = ["languageName": languageName, "languageCode": voiceLanguageCode]
arrVoiceLanguages.append(dictionary)
}
Any help is appreciated.
I don't know why people give down vote to this question.!
Perhaps your arrVoiceLanguages variable declared [String:String!] type and NSLocale.currentLocale().displayNameForKey() function's return type is String?.
So you can try this (I added ! at end to unwrap value).
let languageName = NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: voiceLanguageCode)!
Your arrVoiceLanguages array type should be:
var arrVoiceLanguages = [[String: String?]]()
Or you need to unwrap languageName this way:
guard let languageName = NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: voiceLanguageCode) else {return}
Because NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: voiceLanguageCode) return optional string.
By unwrapping languageName you don't need to change type of your arrVoiceLanguages array. And your code will be:
var arrVoiceLanguages: [Dictionary<String, String!>] = []
for voice in AVSpeechSynthesisVoice.speechVoices() {
let voiceLanguageCode = (voice as AVSpeechSynthesisVoice).language
guard let languageName = NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: voiceLanguageCode) else {return}
let dictionary = ["languageName": languageName, "languageCode": voiceLanguageCode]
arrVoiceLanguages.append(dictionary)
}

error using valueForKey in swift

Why do I get an error when I used valueForKey... I am using same trick like in objectiveC ...
In ObjectiveC, the code is
self.strSubscribe =[responseObject[#"subscribe"] valueForKey:#"subscribe_ids"];
In Swift , the code is
self.strSubscribe = responseObject["subscribe"].valueForKey["subscribe_ids"] as! String
I declare the variables like
var arraySubCategory : NSMutableArray! = NSMutableArray()
var strSubscribe:String!
And I tried to access the value from below response
{
subscribe =
{
"subscribe_ids" = "1,14";
}
}
Edit
It works using Amit and Eric's solution but now for following data
{
data = (
{
"subscribe_ids" = "1,14";
}
);
}
let dictionary = responseObject["data"][0] as! Dictionary<String,AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
OR//
if let dic = responseObject["data"][0] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids
}
but it gives me error:
could not find member 'subscript'
Swift doesn't know the type of responseObject["subscribe"], you have to help the compiler a bit; for example:
if let dic = responseObject["subscribe"] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids // "1,14"
}
UPDATE:
It's still the same problem: the compiler doesn't know the type of responseObject["data"], so when you try to access the subscript there's an error (because you know it's a dictionary inside the array, but the compiler doesn't).
One solution is to give the type to the compiler by declaring an array of dictionaries in the if let condition:
if let arr = responseObject["data"] as? [[String:String]], let ids = arr[0]["subscribe_ids"] {
self.strSubscribe = ids
}
Notice that it's [[String:String]] (array of dictionaries), not [String:String] (dictionary).
Write like this.
let dictionary = responseObject["subscribe"] as! Dictionary<String, AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
Since responseObject["subscribe"] will give a AnyObject? output and AnyObject does not have any member called valueForKey.

Resources