I have a Dictionary and i want to save it to NSUserDefaults(or something else so I can have access to my variables after i have terminated the app) , I found an example:
var saved = NSUserDefaults.standardUserDefaults()
let dict = ["Name": "Paul", "Country": "UK"]
saved.setObject(dict, forKey: "SavedDict")
But when i used it to mine Dictionary it didn't work. (maybe because my dictionary it's a little bit different)
My Dictionary is made like this:
var userDictionary = [Int : Event]()
struct Event {
var sensorName: String
var sensorType: String
var sensorSub: String
}
And i add elements like this:
userDictionary[value] = Event(sensorName: "first", sensorType: "Temp", sensorSub: "Third")
And here is what i tried to do so I can store it.
saved.setObject(userDictionary, forKey: "valueDictionary")
And I get this error:
Cannot convert value of type '[Int : SensorsView.Event]' to expected
argument type 'AnyObject?'
To avoid this error I did this:
self.saved.setObject(self.userDictionary as? AnyObject, forKey: "valueDictionary")
But I can't retrieve what i saved
Unfortunately this question didn't help me after some comments i believe that the goal here is to convert my dictionary to Data (or something else) and after i retrieve it i convert it back to Dictionary
Try to convert the data to NSData and then retrieve like so:
/// Save
NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(object), forKey: key)
/// Read
var data = NSUserDefaults.standardUserDefaults().objectForKey(key) as NSData
var object = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [String: String]
What i think is from the link below you will be able to store the Dictionary into NSUserDefaults
Swift NSUserDefaults not saving Dictionary?
or
Saving dictionary into NSUserDefaults may help
I managed to save my custom Dictionary using Realm!
Instead of a struct I use a different class like this:
import RealmSwift
class Sensors : Object {
dynamic var sensorName = ""
dynamic var sensorType = ""
dynamic var sensorSub = ""
}
and then I fill it like this:
var useOfRealm = try! Realm()
var allSensors = useOfRealm.objects(Sensors.self)
var saving = Sensors()
func fillThis() {
try! useOfRealm.write {
saving.sensorName = "something"
saving.sensorType = "something"
saving.sensorSub = "something"
useOfRealm.add(saving)
}
}
Use the function with parameters so you can fill the 'Dictionary' Dynamically.
Use allSensors so you can retrieve everything that you want.
Related
I want to create a NSMutableDictionary using Swifty-Json.
I have declared dictionary like this
var arrTest = Array<JSON>()
var testDict : JSON = [:]
testDict.dictionaryObject?.updateValue(arrTest[0]["test"][indexPath.item]["xyz"], forKey: "abc")
Now I am unable to setValueForKey in this Dictionary.
Can Someone tell me how to create a NSMutableDictionary using SwiftyJson and also how to insert, update and delete values in this dictionary.
Thanks in advance
Don't use NSMutableDictionary in Swift, use Swift built-in type Dictionary instead. Declaring it as var will make it mutable.
You also don't use updateValue for Dictionary, simply use a subscript:
var testDict : [String : AnyObject] = [:]
let key = "abc"
let value = arrTest[0]["test"][indexPath.item]["xyz"]
testDict[key] = value
// add object
let testobj = ["qwe" : arrTest[0]["test"][indexPath.item]["xyz"]]
dictSelectedOption = JSON(testobj)
//remove objects
dictSelectedOption.dictionaryObject?.removeAll()
I have a class:
class myObject: NSObject {
dynamic var objectId : String?
dynamic var name : String?
dynamic var lastName : String?
dynamic var age : String?
}
In my other class I am getting the value of this class's property:
self.myArray.append(myObject.name!)
I can get the value of myObject.name by adding .name but what if there will be hundreds of properties in my myObject class? For that I want to create a method which can return the properties of my class using a variable:
let myVar = "name"
self.myArray.append(myObject.myVar)
It should append the values of property name, but I am getting an error:
value of myObject has no member `myVar`
and I know why I am getting the error.
How can I get access to properties of my class using a variable? Something like :getValue(String) should return that property of my class.
You should also have a look at NSMutableDictionary, here's a quick example which shows how it works
// initialise a dictionary
var dict = NSMutableDictionary(objects: ["first", "second", 42], forKeys: ["String1", "String2", "Int1"])
// add a new attribute
dict.addEntriesFromDictionary(NSDictionary(object: "New thing", forKey: "String3") as [NSObject : AnyObject])
// access the data
let firstString = dict.valueForKey("String1")
let firstInt = dict.valueForKey("Int1")
// update the data
dict.setValue(99, forKey: "Int1")
let newValue = dict.valueForKey("Int1")
I can be wrong, but as I've already said in a comment, it would be better to use Dictionary and store values in it. Also if you want to access some values with a dot-notation, but still be able to get them by string, you can just create a property and override setter and getter
class MyClass {
var properties = [String: AnyObject]()
var someProperty: String? {
get {
return properties["someProperty"] as? String
}
set {
properties["someProperty"] = newValue
}
}
This way you are able to access value of someProperty both by object.someProperty and object.properties["someProperty"]
You can do it making array of object like following
var arrayOfObjects = [myObject]
and then set an objects values
var firstObject:myObject
myObject.name = "Your name"
myObject.age = "Your age"
...
then append first object to arrayOfObjects
arrayOfObject.append(firstObject)
and you can access it
print("First Object's name: \(arrayOfObjects[0].name)")
I have put an array into NSUserDefaults() like so:
NSUserDefaults.standardUserDefaults().setObject(users, forKey: "usersArray")
NSUserDefaults.standardUserDefaults().synchronize()
Then I pull it out like so:
fetchedUserArray = NSUserDefaults.standardUserDefaults().objectForKey("usersArray")
The problem I am facing is that once it is removed from NSUserDefaults it is of type NSArray, preventing me from manipulating it like a Swift array. I have tried this to convert the type, however the compiler does not recognize the variable "castedUsersArray" when it is used later in the code despite not raising any errors upon type casting:
var fetchedArray = NSUserDefaults.standardUserDefaults().objectForKey("usersArray") as? NSArray
var castedUsersArray = fetchedArray as AnyObject as [String]
I have spent a very long time on this with no success. The type constraints of Swift are driving me nuts.
Thank you,
Nick
You almost had it. Don't cast the objectForKey to an Array but rather an Array containing a certain type like you did with castedUsersArray. Don't throw away type information like you did with fetchedArray.
let users = ["Amy", "Bill", "Cindy"]
NSUserDefaults.standardUserDefaults().setObject(users, forKey: "usersArray")
NSUserDefaults.standardUserDefaults().synchronize()
let fetched = NSUserDefaults.standardUserDefaults().objectForKey("usersArray") as? [String] ?? []
The nil coalescing at the end of the line handles the empty NSUserDefaults case.
NSUserDefaults has a specific method to get your stored string arrays called stringArrayForKey:
let stringArray = ["Hello","playground"]
store your string array
NSUserDefaults.standardUserDefaults().setObject(stringArray, forKey: "stringArray")
load it when needed
if let loadedStringArray = NSUserDefaults.standardUserDefaults().stringArrayForKey("stringArray") {
print(loadedStringArray) // ["Hello", "playground"]
}
I have an dictionary = String: ([(String)], [(Int)], NSDate, Bool, [(String)]) and I attempted to deconstruct it into seperate arrays when then app calls applicationWillTerminate
var codes = [(String)]()
var messages = [[String]]()
var senders = [[Int]]()
var dates = [(NSDate)]()
var bools = [(Bool)]()
var pairs = [[String]]()
for code in self.dictionary.keys {
codes.append(code)
messages.append(self.dictionary[code]!.0)
senders.append(self.dictionary[code]!.1)
dates.append(self.dictionary[code]!.2)
bools.append(self.dictionary[code]!.3)
pairs.append(self.dictionary[code]!.4)
}
self.userDefaultsMessages.setObject(codes, forKey: "userMessagesArrays")
self.userDefaultsSenders.setObject(messages, forKey: "userSentArrays")
self.userDefaultsDates.setObject(senders, forKey: "userDatesArray")
self.userDefaultsDeletedBool.setObject(dates, forKey: "userDeletedArrays")
self.userDefaultsPairs.setObject(bools, forKey: "userPairsArrays")
self.userDefaultsCodeKeys.setObject(pairs, forKey: "userCodesArrays")
self.userDefaultsCodeKeys.synchronize()
self.userDefaultsMessages.synchronize()
self.userDefaultsSenders.synchronize()
self.userDefaultsDates.synchronize()
self.userDefaultsDeletedBool.synchronize()
self.userDefaultsPairs.synchronize()
and then I attempt to pull it all back together when the app calls applicationDidBecomeActive
//read
if let savedCodesArray : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userCodesArrays") {
self.userCodes = savedCodesArray! as! [String]
if let savedMessagesArray : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userMessagesArrays") {
self.Usermessages = savedMessagesArray! as! [[String]]
if let savedSendersArray : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userSentArrays") {
self.Usersenders = savedSendersArray! as! [[Int]]
if let savedDatesArray : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userDatesArray") {
self.Userdates = savedDatesArray! as! [NSDate]
if let savedBools : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userDeletedArrays") {
self.Userbools = savedBools! as! [Bool]
if let savedPairs : AnyObject? = self.userDefaultsCodeKeys.objectForKey("userPairsArrays") {
self.Userpairs = savedPairs! as! [[String]]
var indexPath: Int = 0
for code in self.userCodes {
self.dictionary[code]! = [self.Usermessages[indexPath], self.Usermessages[indexPath], self.Userdates[indexPath], self.Userbools[indexPath], self.Userpairs[indexPath]]
}
}
}
}
}
}
}
I am fairly new to iOS development and could use help, how would i save the single dictionary = String: ([(String)], [(Int)], NSDate, Bool, [(String)]) to NSUserDefaults and then later read it.. the documentation was not very helpful since it only worked with simple dictionaries
the code looks incredibly cumbersome so I know I can't be doing it right. It should be a simple solution since I only have one variable to save to NSUserDefaults.
Short answer: You can't.
NSUserDefaults will only record "property list objects" (dictionaries, arrays, strings, numbers (integer and float), dates, binary data, and Boolean values).
You can't save any other types of data into NSUserDefaults, or into a property list. The only solution is to convert other data types into those types.
Tuples are not one of those types, so they can't be saved into user defaults.
First, your interaction with NSUserDefaults is completely wrong. You only need to interact with the shared NSUserDefaults.sharedUserDefaults() instance, not create separate instances, which seems to be what you're doing (i.e. userDefaultsMessages, userDefaultsSenders, etc.).
Second, you don't need to call synchronize() at all. There are very few conditions under which you need to call it manually, and this isn't one of them.
Third, the easiest way to store a particular tuple in NSUserDefaults is to convert it into an Array (or NSArray) and store the result. Of course, this assumes that the tuple contains only types that can be serialized, which your example seems to contain. Unfortunately there's no general solution to this, but creating an array from a tuple is straight forward, as you can just map the tuple indices to array indices.
Finally, such large tuples are usually the result of poor design somewhere along the line. Perhaps refactoring would help resolve your storage issue?
I have a storyboard which start with a login page. And I have a User class like this
class User {
// Properties
var firmCode : String
var firmId : String
var userId : String
// Default Initializer
init() {
self.firmCode = ""
self.firmId = ""
self.userId = ""
}
// Defult Initializer with prams
init(firmCode: String, firmId: String, userId: String) {
self.firmCode = firmCode
self.firmId = firmId
self.userId = userId
}
}
I am generating some values in login page, and I can create my User object with these values.
Now I want to make this object global and use this user object in all scene.
How to pass this object to other scenes? For example I want to pass this values with my object to an embed static table view controller like this
Note: Does it matter, the embed controller has a tab bar controller? I guess I need to use my delegate file?
EDIT:
Now I have created my global object like this:
// test value
let firmId = "Company Id"
// Creating user object without user class declaration
NSUserDefaults.standardUserDefaults().setObject(firmId, forKey: "testFirmId")
And trying to get my object like this:
// Creating user variable in other scene by globally
let getValue : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("testFirmId")
// checking
println(getValue!)
AND done, return my value on termanal. All work until here.
But now the value return to me as AnyObject, I need the convert it String to apply like this:
someLabel.text = getValue!
You can use NSUserDefaults for that like you can store your object this way:
NSUserDefaults.standardUserDefaults().setObject(YourObject, forKey: "YouKey")
After that you can access it in any scene like:
let yourObject: AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("YouKey")
Hope It will help you.
EDIT:
NSUserDefaults is limited in the types it can handle: NSData, NSString, NSNumber, NSDate, NSArray, and NSDictionary. Thus no Swift objects or structs can be saved.
From the Apple NSUserDefaults Docs:
A default object must be a property list, that is, an instance of (or
for collections a combination of instances of): NSData, NSString,
NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any
other type of object, you should typically archive it to create an
instance of NSData.
And if you are using NSUserDefaults then you can directly store your instance like shown below:
NSUserDefaults.standardUserDefaults().setObject(test, forKey: "firmCode")
NSUserDefaults.standardUserDefaults().setObject(test, forKey: "firmId")
NSUserDefaults.standardUserDefaults().setObject(test, forKey: "userId")
You Don't need model class for that.
var user = User()
self.user.firmCode = 1
//Assign value to other variables
//Save User object in NSUserDefaults as like this
User.saveUserObject(user)
//Function For Save User
class func saveUserObject(user : User){
let userKey = "UserData \(user.userID)"
NSUserDefaults.standardUserDefaults().setObject(data, forKey: userKey)
}
//Get User Object from NSUserDefaults
class func getUserObject(userIDValue : NSNumber) -> User? {
let userKey = "UserData \(userIDValue)"
if let data = NSUserDefaults.standardUserDefaults().objectForKey(userKey) as? NSData {
return data as? User
}
return nil
}