I am having a problem saving and loading up my difficulty integer. I have a button pushed to decide it on one view:
(This is one difficulty)
Difficulty + 1
let SecondDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
SecondDefaults.setObject(Difficulty, forKey: "Difficulty")
SecondDefaults.synchronize()
On another view under viewDidLoad for the loading:
let SecondDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var difficulty = SecondDefaults.valueForKey("Difficulty")?.integerValue
SecondDefaults.synchronize()
Difficulty = difficulty!.stringByTrimmingCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).toInt()!
You need to change:
var difficulty = SecondDefaults.valueForKey("Difficulty") as? String
to
var difficulty = SecondDefaults.valueForKey("Difficulty")?.stringValue
I don't know why you need to convert the integer to string. You only need the following code for getting an integer from NSUserDefaults no need to convert it to string.
let SecondDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var difficulty = SecondDefaults.valueForKey("Difficulty")?.integerValue
Your issue lies on this line:
var difficulty = SecondDefaults.valueForKey("Difficulty") as? String
The problem is that the value may be a String or it may nil. Who knows? The as? keyword indicates that the cast may fail, so difficulty is a String optional, which you implicitly unwrap. Anything you unwrap as nil will give you a runtime error.
Assuming that Difficulty from your second code snippet is of type Int, this should work:
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
let maybeDifficulty = defaults.valueForKey("Difficulty") as? Int
if let difficulty = maybeDifficulty {
Difficulty = difficulty
} else {
println("Difficulty is not an Int or may be nil")
}
Related
Below I try to make an array ChatListings, but it doesn't work.
let chatRef = FIRDatabase.database().reference().child("chatListings")
override func viewDidLoad() {
super.viewDidLoad()
let firstQuery = chatRef.queryOrdered(byChild: "userID").queryEqual(toValue: userID)
firstQuery.observe(FIRDataEventType.value, with: { snapshot in
for child in snapshot.children {
print("child is \(child)")
if let dict = snapshot.value as? Dictionary<String, AnyObject>{
print("dict is \(dict)")
let roomKey = dict["chatRoomKey"] as! String
let oUID = dict["otherUserID"] as! String
let oUserName = dict["otherUserName"] as! String
let oProfilePic = dict["otherUserProfilePic"] as! String
let userIDTemp = dict["userID"] as! String
chatListing = ChatListing(chatRoomKey: roomKey, UID: userIDTemp, name: oUserName, otherUserID: oUID, otherUserProfilePicURL: oProfilePic)
chatListings.append(chatListing)
}
}
print("chatListings = \(chatListings)")
})
}
This crashes saying that the compiler unexpectedly found nil while unwrapping an Optional value. I don't know why it won't work. I've tried every which way I can find to extract the data that the compiler reads moments before crashing or failing to fill an array of my 'chatlisting' objects.
Here's an example of the data that the compiler reads but cannot extract with maybe 4 different coding attempts:
"-KjdSF97Q2z3afXzkwQ9": {
chatRoomKey = "-KjdSF97Q2z3afXzkwQ9";
messages = {
"-KjdSOVTsg8jEy6SeEA2" = {
MediaType = PHOTO;
fileUrl = "https://firebasestorage.googleapis.com/v0/b/preollify.appspot.com/o/mget8KN2nHe4sOhbnWTixYvCOrr2%2F515963239.371526?alt=media&token=6cb12ec1-5bdb-43a1-ab49-90c90570b341";
senderId = mget8KN2nHe4sOhbnWTixYvCOrr2;
senderName = Michael;
};
"-KjdSPxpNT0pkQ1y5-_1" = {
MediaType = VIDEO;
fileUrl = "https://firebasestorage.googleapis.com/v0/b/preollify.appspot.com/o/mget8KN2nHe4sOhbnWTixYvCOrr2%2F515963229.282051?alt=media&token=04671c8e-d7f1-49f2-81d0-09836c034ae2";
senderId = mget8KN2nHe4sOhbnWTixYvCOrr2;
senderName = Michael;
};
"-KjdVaVTfbaC-3S-91-A" = {
MediaType = TEXT;
senderId = mget8KN2nHe4sOhbnWTixYvCOrr2;
senderName = Michael;
text = The;
};
};
otherUserID = aRandomUser3611;
otherUserName = Michael;
otherUserProfilePic = "https://firebasestorage.googleapis.com/v0/b/preollify.appspot.com/o/ProfilePictures%2Fmget8KN2nHe4sOhbnWTixYvCOrr2%2FmediumProfilePicture.jpg?alt=media&token=d88afa5d-0db7-4ce2-95c9-3038ff592e9f";
userID = mget8KN2nHe4sOhbnWTixYvCOrr2;
I'm trying to extract all the data but the messages part, which I plan on doing later in the app.
This data (excluding the "messages" part) gets written in the chatViewController's viewDidLoad like this:
let preMessageRef = chatRef.childByAutoId()
chatListingID = preMessageRef.key
let initialChatRoomData = ["chatRoomKey": chatListingID, "otherUserID": otherUID, "otherUserName": otherUserName, "otherUserProfilePic": otherUserProfilePicURLString, "userID": userID]
preMessageRef.setValue(initialChatRoomData)
Retrieving data from Firebase Database has been completely hit or miss for me, with copying the successful attempts of extracting data rarely working twice. Their documentation is minimal to the point of leaving out way too much as it provides little help for how to extract data in real world contexts. Why do people like Firebase? It has been a very frustrating experience working with Firebase and I definitely regret it. But it's probably too late to turn back and go with something better, i.e. a platform that provides clear instruction for how to get it to work.
I think you just have a silly typo. Try this:
let childData = child as! FIRDataSnapshot
print("child key: \(childData.key)")
if let dict = childData.value as? Dictionary<String, AnyObject> {
...
}
that is, use child instead of snapshot.
Update. Turns out using NSDictionary, rather than Dictionary, fixed the dict constant crashes. But, besides compiler bugs, still not clear why...
I'm trying to save key value in the NSUserDefaults but is not been save. Here is my code:
func saveData() {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject("blablabla", forKey:"data")
userDefaults.synchronize()
}
Any of you knows why this data is not been save?
I'll really appreciate your help.
Swift 2.x:
According with Apple sources:
public func objectForKey(defaultName: String) -> AnyObject?
to retrieve your value you could use:
if let value = userDefaults.objectForKey("data") {
// do whatever you want with your value
// P.S. value could be numeric,string,..
}
I think you are doing it wrong, try like this:
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject("blablabla", forKey:"data")
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey("data") {
print(name)
}
You won't be able to access a string with dictionaryForKey because string is not a dictionary value type. Let me know if you need any further help.
You won't be able to access a string with 'dictionaryForKey' because a string is not a dictionary value type. You'll need to use:
if let savedString = userDefaults.stringForKey("data") {
print(savedString)
}
If you have any further questions feel free to let me know :)
Hi I have a problem trying to save my data to a plist, my class looks like this:
struct timerData {
var timerCount: NSTimeInterval
var timerText: String
var timerRunning: Bool
var soundSwitch: Bool
var vibrateSwitch: Bool
var alertInfo: [alertData?]
//initialisation
init(timerCounter: Double, timerText: String, soundSwitch: Bool, vibrateSwitch: Bool, alertInfo: [alertData?]) {
self.timerCount = timerCounter
self.timerRunning = false
self.timerText = timerText
self.soundSwitch = soundSwitch
self.vibrateSwitch = vibrateSwitch
self.alertInfo = alertInfo
}
}
I've figured out how to save each part individually to arrays in the plist, but i realised it would be much easier to save an array of the timerData, since it's already set up.
My plist file directory is coming from the app delegate as i'm using tab views
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let pathForThePlistFile = appDelegate.plistPathInDocument
//This is the data structure
let namesArray = NSMutableDictionary(contentsOfFile: pathForThePlistFile)
//creating array for the data to be passed in
var timerDataArray = [timerData]()
//initialise values to that struct
var timerDataTest = timerData(timerCounter: self.timerCounter.countDownDuration, timerText: (self.promptText?.text)!, soundSwitch: self.soundSwitch.on, vibrateSwitch: self.vibrateSwitch.on, alertInfo: self.alertDataSource)
//append to array
timerDataArray.append(timerDataTest)
print(timerDataArray)
//OPTION 1: found this on another stack thread **This fails
NSKeyedArchiver.archiveRootObject(timerDataArray as! AnyObject, toFile: pathForThePlistFile)
//OPTION 2: set the value to an array in the plist ** This also fails because of type
namesArray!.setValue(timerDataArray as? AnyObject, forKey: "data1")
print(namesArray)
// Save to plist
namesArray!.writeToFile(pathForThePlistFile, atomically: true)
I know it's an issue with my array type, but i'm not sure how to cast it to a type that will be accepted in the plist, i've looked at loads of already answered questions and tried loads but I can't figure it out. Thanks in advance for any help
Im trying to retrieve a Int value from a userdefault and show it in a input field, but I keep getting the fatal error: unexpectedly found nil while unwrapping an Optional value, it must be a wrong placed ! or ? somewhere in this code. I have used hours now :-(
func LoadFromDefaultDistances(){
if let v = defaults.objectForKey("DriverMin") as? NSInteger {
inputDriverMin.text = String(defaults.objectForKey("DriverMin") as! NSInteger)
}
}
Use this code to save the value.
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Your in value", forKey: "myIntValue")
defaults.synchronize()
And use this code to get it back.
let defaults = NSUserDefaults.standardUserDefaults()
if let theInt = defaults.stringForKey("myIntValue")
{
inputDriverMin.text = theInt
}
I'm pretty new to Swift, and I've managed to get pretty stuck.
I'm trying to retrieve data from NSUserDefaults and store it in an array (tasks):
#lazy var tasks: NSArray = {
let def = NSUserDefaults.standardUserDefaults()
let obj: AnyObject? = def.objectForKey("tasks")
return obj as NSArray
}()
All I'm getting is a warning: EXE_BAD_INSTRUCTION on line 3.
Also to note that I haven't actually set any data yet, but what I'm aiming for is that if there is no data, I want the array to be empty. I'll be using the data to populate a table view.
Now using a var instead of a constant:
#lazy var tasks: NSArray = {
let def = NSUserDefaults.standardUserDefaults()
var obj: AnyObject? = {
return def.objectForKey("tasks")
}()
return obj as NSArray
}()
The error has now moved to the return line.
I think the problem here is that you are attempting to cast nil to a non-optional type and return it. Swift does not allow that. The best way to solve this would be the following:
#lazy tasks: NSArray = {
let defaults = NSUserDefaults.standardUserDefaults()
if let array = defaults.arrayForKey("tasks") as? NSArray {
return array
}
return NSArray()
}
Using Swift's if let syntax combined with the as? operator lets you assign and safe cast in one line. Since your method does not return an optional, you must return a valid value if that cast fails.