Saving Firebase snapshot array to NSUserDefaults
I am using Swift to retrieve data from my Firebase database. When the user first logs in, I'd like to save the 'places' from my Firebase snapshot as a UserDefault.
static func getAllPlaces(){
databaseRef = Database.database().reference()
databaseRef.database.reference().child("places").observe(.childAdded) { (snapshot: DataSnapshot) in
if let value = snapshot.value as? NSDictionary {
let place = Place()
let id = value["id"] as? String ?? "ID not found"
let title = value["title"] as? String ?? "Title not found"
let type = value["type"] as? String ?? ""
place.id = id
place.title = title
place.type = type
DispatchQueue.global().async {
// Something here to append place data to UserDefaults?
places.append(place) // appends to NSObject for later use
}
}
}
}
The current code works fine - I just need to add something to get it stored so I can grab it later.
Bonus question: I am storing a good few hundred snapshots in the Firebase database. The reason I want to store them on the device is so that the user doesn't have to keep downloading the data. Is this a good idea? Would it take up a lot of memory?
Any help would be appreciated.
swift firebase firebase-realtime-database nsuserdefaults
add a comment |
I am using Swift to retrieve data from my Firebase database. When the user first logs in, I'd like to save the 'places' from my Firebase snapshot as a UserDefault.
static func getAllPlaces(){
databaseRef = Database.database().reference()
databaseRef.database.reference().child("places").observe(.childAdded) { (snapshot: DataSnapshot) in
if let value = snapshot.value as? NSDictionary {
let place = Place()
let id = value["id"] as? String ?? "ID not found"
let title = value["title"] as? String ?? "Title not found"
let type = value["type"] as? String ?? ""
place.id = id
place.title = title
place.type = type
DispatchQueue.global().async {
// Something here to append place data to UserDefaults?
places.append(place) // appends to NSObject for later use
}
}
}
}
The current code works fine - I just need to add something to get it stored so I can grab it later.
Bonus question: I am storing a good few hundred snapshots in the Firebase database. The reason I want to store them on the device is so that the user doesn't have to keep downloading the data. Is this a good idea? Would it take up a lot of memory?
Any help would be appreciated.
swift firebase firebase-realtime-database nsuserdefaults
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48
add a comment |
I am using Swift to retrieve data from my Firebase database. When the user first logs in, I'd like to save the 'places' from my Firebase snapshot as a UserDefault.
static func getAllPlaces(){
databaseRef = Database.database().reference()
databaseRef.database.reference().child("places").observe(.childAdded) { (snapshot: DataSnapshot) in
if let value = snapshot.value as? NSDictionary {
let place = Place()
let id = value["id"] as? String ?? "ID not found"
let title = value["title"] as? String ?? "Title not found"
let type = value["type"] as? String ?? ""
place.id = id
place.title = title
place.type = type
DispatchQueue.global().async {
// Something here to append place data to UserDefaults?
places.append(place) // appends to NSObject for later use
}
}
}
}
The current code works fine - I just need to add something to get it stored so I can grab it later.
Bonus question: I am storing a good few hundred snapshots in the Firebase database. The reason I want to store them on the device is so that the user doesn't have to keep downloading the data. Is this a good idea? Would it take up a lot of memory?
Any help would be appreciated.
swift firebase firebase-realtime-database nsuserdefaults
I am using Swift to retrieve data from my Firebase database. When the user first logs in, I'd like to save the 'places' from my Firebase snapshot as a UserDefault.
static func getAllPlaces(){
databaseRef = Database.database().reference()
databaseRef.database.reference().child("places").observe(.childAdded) { (snapshot: DataSnapshot) in
if let value = snapshot.value as? NSDictionary {
let place = Place()
let id = value["id"] as? String ?? "ID not found"
let title = value["title"] as? String ?? "Title not found"
let type = value["type"] as? String ?? ""
place.id = id
place.title = title
place.type = type
DispatchQueue.global().async {
// Something here to append place data to UserDefaults?
places.append(place) // appends to NSObject for later use
}
}
}
}
The current code works fine - I just need to add something to get it stored so I can grab it later.
Bonus question: I am storing a good few hundred snapshots in the Firebase database. The reason I want to store them on the device is so that the user doesn't have to keep downloading the data. Is this a good idea? Would it take up a lot of memory?
Any help would be appreciated.
swift firebase firebase-realtime-database nsuserdefaults
swift firebase firebase-realtime-database nsuserdefaults
edited Nov 22 at 19:47
Frank van Puffelen
227k28369396
227k28369396
asked Nov 22 at 18:47
Ryan
3819
3819
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48
add a comment |
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48
add a comment |
1 Answer
1
active
oldest
votes
One way to save custom classes/data to UserDefaults is to encode them like this:
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: place)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
Then you can decode it like this:
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
let decodedPlace = NSKeyedUnarchiver.unarchiveObject(with: decodedData) as! Place
}
Updated for swift 4 and iOS 12:
do {
let encodedData: Data = try NSKeyedArchiver.archivedData(withRootObject: place, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
} catch {
//Handle Error
}
do {
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
if let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? Place {
//Do Something with decodedPlace
}
}
}
catch {
//Handle Error
}
Thank you for your answer. I receive this warning:'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?
– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why doeslet decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return<Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?
– Ryan
Nov 23 at 12:11
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436673%2fsaving-firebase-snapshot-array-to-nsuserdefaults%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
One way to save custom classes/data to UserDefaults is to encode them like this:
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: place)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
Then you can decode it like this:
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
let decodedPlace = NSKeyedUnarchiver.unarchiveObject(with: decodedData) as! Place
}
Updated for swift 4 and iOS 12:
do {
let encodedData: Data = try NSKeyedArchiver.archivedData(withRootObject: place, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
} catch {
//Handle Error
}
do {
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
if let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? Place {
//Do Something with decodedPlace
}
}
}
catch {
//Handle Error
}
Thank you for your answer. I receive this warning:'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?
– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why doeslet decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return<Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?
– Ryan
Nov 23 at 12:11
|
show 2 more comments
One way to save custom classes/data to UserDefaults is to encode them like this:
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: place)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
Then you can decode it like this:
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
let decodedPlace = NSKeyedUnarchiver.unarchiveObject(with: decodedData) as! Place
}
Updated for swift 4 and iOS 12:
do {
let encodedData: Data = try NSKeyedArchiver.archivedData(withRootObject: place, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
} catch {
//Handle Error
}
do {
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
if let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? Place {
//Do Something with decodedPlace
}
}
}
catch {
//Handle Error
}
Thank you for your answer. I receive this warning:'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?
– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why doeslet decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return<Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?
– Ryan
Nov 23 at 12:11
|
show 2 more comments
One way to save custom classes/data to UserDefaults is to encode them like this:
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: place)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
Then you can decode it like this:
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
let decodedPlace = NSKeyedUnarchiver.unarchiveObject(with: decodedData) as! Place
}
Updated for swift 4 and iOS 12:
do {
let encodedData: Data = try NSKeyedArchiver.archivedData(withRootObject: place, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
} catch {
//Handle Error
}
do {
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
if let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? Place {
//Do Something with decodedPlace
}
}
}
catch {
//Handle Error
}
One way to save custom classes/data to UserDefaults is to encode them like this:
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: place)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
Then you can decode it like this:
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
let decodedPlace = NSKeyedUnarchiver.unarchiveObject(with: decodedData) as! Place
}
Updated for swift 4 and iOS 12:
do {
let encodedData: Data = try NSKeyedArchiver.archivedData(withRootObject: place, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "place")
UserDefaults.standard.synchronize()
} catch {
//Handle Error
}
do {
if UserDefaults.standard.object(forKey: "place") != nil{
let decodedData = UserDefaults.standard.object(forKey: "place") as! Data
if let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? Place {
//Do Something with decodedPlace
}
}
}
catch {
//Handle Error
}
edited Nov 23 at 12:30
answered Nov 22 at 18:52
Arie Pinto
703614
703614
Thank you for your answer. I receive this warning:'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?
– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why doeslet decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return<Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?
– Ryan
Nov 23 at 12:11
|
show 2 more comments
Thank you for your answer. I receive this warning:'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?
– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why doeslet decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return<Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?
– Ryan
Nov 23 at 12:11
Thank you for your answer. I receive this warning:
'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder 'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
Thank you for your answer. I receive this warning:
'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead
and for the decoder 'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead
– Ryan
Nov 22 at 23:22
1
1
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
i updated the answer for iOS 12 and swift 4 @Ryan
– Arie Pinto
Nov 23 at 0:45
I seem to be receiving this
-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?– Ryan
Nov 23 at 11:55
I seem to be receiving this
-[Place encodeWithCoder:]: unrecognized selector sent to instance
any ideas?– Ryan
Nov 23 at 11:55
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Yes, your Place class should conform to the NSCoding protocol, please refer to this discussion stackoverflow.com/questions/22168753/…
– Arie Pinto
Nov 23 at 11:58
Thank you! I'm nearly there - why does
let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return <Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?– Ryan
Nov 23 at 12:11
Thank you! I'm nearly there - why does
let decodedPlace = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as! Place
return <Place: 0x283245c00>
? I tried printing decodedPlace.title but it returns nil?– Ryan
Nov 23 at 12:11
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436673%2fsaving-firebase-snapshot-array-to-nsuserdefaults%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Limit yourself to one question per post please. If your bonus question is a new question, put it in a new post. But note that you might want to do some profiling of your app yourself before doing that.
– Frank van Puffelen
Nov 22 at 19:48