Is there a way to unarchive object which is being saved in userdefaults using...
I have a class which creates an object ( two strings and one picture of NSData) on the unarchive process, I am getting a pointer. I assume this is where my object lives in memory. Which would be the most appropriate way to unarchive this already saved object from the memory.
This a project I want to make an app which by using an API you can see recipes. I am trying to make another feature where the user can upload their own recipes. since this is my first app ever I am trying to learn about data persistence.
The code seems to work fine, except the part where I need to read unarchive the data from the UserDefaults.
class myRecipes: NSObject, NSCoding {
var publisher: String
var image_url: NSData
var title: String
enum SerializationError:Error {
case missing(String)
case invalid(String, Any)
}
init(title: String, publisher: String, image_url: NSData) throws {
self.publisher = publisher
self.image_url = image_url
self.title = title
}
required convenience init(coder aDecoder: NSCoder) {
let publisher = aDecoder.decodeObject(forKey: "publisher") as! String
let image_url = aDecoder.decodeObject(forKey: "image_url") as! NSData
let title = aDecoder.decodeObject(forKey: "title") as! String
try! self.init(title: title, publisher: publisher, image_url: image_url)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(publisher, forKey: "publisher")
aCoder.encode(image_url, forKey: "image_url")
aCoder.encode(title, forKey: "title")
}
}
func applicationDidEnterBackground(_ application: UIApplication) {
let userDefaults = UserDefaults.standard
let encodedData: Data = try! NSKeyedArchiver.archivedData(withRootObject: myRecipess, requiringSecureCoding: false)
userDefaults.set(encodedData, forKey: "myRecipess")
userDefaults.synchronize()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "myRecipess") as! Data
let decodedTeams = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [myRecipes]
print("decodedTeams")
print(decodedTeams)
}
I expect to have the data retrieved from the memory.
ios swift
add a comment |
I have a class which creates an object ( two strings and one picture of NSData) on the unarchive process, I am getting a pointer. I assume this is where my object lives in memory. Which would be the most appropriate way to unarchive this already saved object from the memory.
This a project I want to make an app which by using an API you can see recipes. I am trying to make another feature where the user can upload their own recipes. since this is my first app ever I am trying to learn about data persistence.
The code seems to work fine, except the part where I need to read unarchive the data from the UserDefaults.
class myRecipes: NSObject, NSCoding {
var publisher: String
var image_url: NSData
var title: String
enum SerializationError:Error {
case missing(String)
case invalid(String, Any)
}
init(title: String, publisher: String, image_url: NSData) throws {
self.publisher = publisher
self.image_url = image_url
self.title = title
}
required convenience init(coder aDecoder: NSCoder) {
let publisher = aDecoder.decodeObject(forKey: "publisher") as! String
let image_url = aDecoder.decodeObject(forKey: "image_url") as! NSData
let title = aDecoder.decodeObject(forKey: "title") as! String
try! self.init(title: title, publisher: publisher, image_url: image_url)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(publisher, forKey: "publisher")
aCoder.encode(image_url, forKey: "image_url")
aCoder.encode(title, forKey: "title")
}
}
func applicationDidEnterBackground(_ application: UIApplication) {
let userDefaults = UserDefaults.standard
let encodedData: Data = try! NSKeyedArchiver.archivedData(withRootObject: myRecipess, requiringSecureCoding: false)
userDefaults.set(encodedData, forKey: "myRecipess")
userDefaults.synchronize()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "myRecipess") as! Data
let decodedTeams = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [myRecipes]
print("decodedTeams")
print(decodedTeams)
}
I expect to have the data retrieved from the memory.
ios swift
add a comment |
I have a class which creates an object ( two strings and one picture of NSData) on the unarchive process, I am getting a pointer. I assume this is where my object lives in memory. Which would be the most appropriate way to unarchive this already saved object from the memory.
This a project I want to make an app which by using an API you can see recipes. I am trying to make another feature where the user can upload their own recipes. since this is my first app ever I am trying to learn about data persistence.
The code seems to work fine, except the part where I need to read unarchive the data from the UserDefaults.
class myRecipes: NSObject, NSCoding {
var publisher: String
var image_url: NSData
var title: String
enum SerializationError:Error {
case missing(String)
case invalid(String, Any)
}
init(title: String, publisher: String, image_url: NSData) throws {
self.publisher = publisher
self.image_url = image_url
self.title = title
}
required convenience init(coder aDecoder: NSCoder) {
let publisher = aDecoder.decodeObject(forKey: "publisher") as! String
let image_url = aDecoder.decodeObject(forKey: "image_url") as! NSData
let title = aDecoder.decodeObject(forKey: "title") as! String
try! self.init(title: title, publisher: publisher, image_url: image_url)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(publisher, forKey: "publisher")
aCoder.encode(image_url, forKey: "image_url")
aCoder.encode(title, forKey: "title")
}
}
func applicationDidEnterBackground(_ application: UIApplication) {
let userDefaults = UserDefaults.standard
let encodedData: Data = try! NSKeyedArchiver.archivedData(withRootObject: myRecipess, requiringSecureCoding: false)
userDefaults.set(encodedData, forKey: "myRecipess")
userDefaults.synchronize()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "myRecipess") as! Data
let decodedTeams = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [myRecipes]
print("decodedTeams")
print(decodedTeams)
}
I expect to have the data retrieved from the memory.
ios swift
I have a class which creates an object ( two strings and one picture of NSData) on the unarchive process, I am getting a pointer. I assume this is where my object lives in memory. Which would be the most appropriate way to unarchive this already saved object from the memory.
This a project I want to make an app which by using an API you can see recipes. I am trying to make another feature where the user can upload their own recipes. since this is my first app ever I am trying to learn about data persistence.
The code seems to work fine, except the part where I need to read unarchive the data from the UserDefaults.
class myRecipes: NSObject, NSCoding {
var publisher: String
var image_url: NSData
var title: String
enum SerializationError:Error {
case missing(String)
case invalid(String, Any)
}
init(title: String, publisher: String, image_url: NSData) throws {
self.publisher = publisher
self.image_url = image_url
self.title = title
}
required convenience init(coder aDecoder: NSCoder) {
let publisher = aDecoder.decodeObject(forKey: "publisher") as! String
let image_url = aDecoder.decodeObject(forKey: "image_url") as! NSData
let title = aDecoder.decodeObject(forKey: "title") as! String
try! self.init(title: title, publisher: publisher, image_url: image_url)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(publisher, forKey: "publisher")
aCoder.encode(image_url, forKey: "image_url")
aCoder.encode(title, forKey: "title")
}
}
func applicationDidEnterBackground(_ application: UIApplication) {
let userDefaults = UserDefaults.standard
let encodedData: Data = try! NSKeyedArchiver.archivedData(withRootObject: myRecipess, requiringSecureCoding: false)
userDefaults.set(encodedData, forKey: "myRecipess")
userDefaults.synchronize()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "myRecipess") as! Data
let decodedTeams = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [myRecipes]
print("decodedTeams")
print(decodedTeams)
}
I expect to have the data retrieved from the memory.
ios swift
ios swift
edited Dec 30 '18 at 5:59
vadian
146k13157175
146k13157175
asked Dec 30 '18 at 4:13
Tony DoublemanTony Doubleman
31
31
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
In Swift 4 it's highly recommended to use the Codable protocol to archive data.
First of all use a struct and name it in singular form
struct Recipe : Codable {
var publisher: String
var imageUrl: Data
var title: String
}
Then you have a data source array
var recipes = [Recipe]()
To save data write
func applicationDidEnterBackground(_ application: UIApplication) {
do {
let encodedData = try PropertyListEncoder().encode(recipes)
UserDefaults.standard.set(encodedData, forKey: "recipes")
} catch { print(error) }
}
To load data write
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
if let decoded = UserDefaults.standard.data(forKey: "recipes") {
do {
recipes = try PropertyListDecoder().decode([Recipe].self, from: decoded)
return
} catch {
print(error)
}
}
recipes =
}
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's[Recipe].self, not[[Recipe]]and I forgot thetrybeforePropertyListDecoder(). Answer updated.
– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets aroundRecipe. Actually there is only one pair.
– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
|
show 3 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%2f53975223%2fis-there-a-way-to-unarchive-object-which-is-being-saved-in-userdefaults-using-un%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
In Swift 4 it's highly recommended to use the Codable protocol to archive data.
First of all use a struct and name it in singular form
struct Recipe : Codable {
var publisher: String
var imageUrl: Data
var title: String
}
Then you have a data source array
var recipes = [Recipe]()
To save data write
func applicationDidEnterBackground(_ application: UIApplication) {
do {
let encodedData = try PropertyListEncoder().encode(recipes)
UserDefaults.standard.set(encodedData, forKey: "recipes")
} catch { print(error) }
}
To load data write
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
if let decoded = UserDefaults.standard.data(forKey: "recipes") {
do {
recipes = try PropertyListDecoder().decode([Recipe].self, from: decoded)
return
} catch {
print(error)
}
}
recipes =
}
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's[Recipe].self, not[[Recipe]]and I forgot thetrybeforePropertyListDecoder(). Answer updated.
– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets aroundRecipe. Actually there is only one pair.
– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
|
show 3 more comments
In Swift 4 it's highly recommended to use the Codable protocol to archive data.
First of all use a struct and name it in singular form
struct Recipe : Codable {
var publisher: String
var imageUrl: Data
var title: String
}
Then you have a data source array
var recipes = [Recipe]()
To save data write
func applicationDidEnterBackground(_ application: UIApplication) {
do {
let encodedData = try PropertyListEncoder().encode(recipes)
UserDefaults.standard.set(encodedData, forKey: "recipes")
} catch { print(error) }
}
To load data write
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
if let decoded = UserDefaults.standard.data(forKey: "recipes") {
do {
recipes = try PropertyListDecoder().decode([Recipe].self, from: decoded)
return
} catch {
print(error)
}
}
recipes =
}
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's[Recipe].self, not[[Recipe]]and I forgot thetrybeforePropertyListDecoder(). Answer updated.
– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets aroundRecipe. Actually there is only one pair.
– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
|
show 3 more comments
In Swift 4 it's highly recommended to use the Codable protocol to archive data.
First of all use a struct and name it in singular form
struct Recipe : Codable {
var publisher: String
var imageUrl: Data
var title: String
}
Then you have a data source array
var recipes = [Recipe]()
To save data write
func applicationDidEnterBackground(_ application: UIApplication) {
do {
let encodedData = try PropertyListEncoder().encode(recipes)
UserDefaults.standard.set(encodedData, forKey: "recipes")
} catch { print(error) }
}
To load data write
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
if let decoded = UserDefaults.standard.data(forKey: "recipes") {
do {
recipes = try PropertyListDecoder().decode([Recipe].self, from: decoded)
return
} catch {
print(error)
}
}
recipes =
}
In Swift 4 it's highly recommended to use the Codable protocol to archive data.
First of all use a struct and name it in singular form
struct Recipe : Codable {
var publisher: String
var imageUrl: Data
var title: String
}
Then you have a data source array
var recipes = [Recipe]()
To save data write
func applicationDidEnterBackground(_ application: UIApplication) {
do {
let encodedData = try PropertyListEncoder().encode(recipes)
UserDefaults.standard.set(encodedData, forKey: "recipes")
} catch { print(error) }
}
To load data write
func applicationDidBecomeActive(_ application: UIApplication) {
// set the notification badge to 0.
application.applicationIconBadgeNumber = 0
// decode the use's recipes.
if let decoded = UserDefaults.standard.data(forKey: "recipes") {
do {
recipes = try PropertyListDecoder().decode([Recipe].self, from: decoded)
return
} catch {
print(error)
}
}
recipes =
}
edited Dec 30 '18 at 9:00
answered Dec 30 '18 at 6:12
vadianvadian
146k13157175
146k13157175
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's[Recipe].self, not[[Recipe]]and I forgot thetrybeforePropertyListDecoder(). Answer updated.
– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets aroundRecipe. Actually there is only one pair.
– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
|
show 3 more comments
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's[Recipe].self, not[[Recipe]]and I forgot thetrybeforePropertyListDecoder(). Answer updated.
– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets aroundRecipe. Actually there is only one pair.
– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
Thank you for your answer, I tried to use your code, I am getting an error on the recipes = PropertyListDecoder().decode([Recipe].self, from: decoded) saying: Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)' which confuses me even more.
– Tony Doubleman
Dec 30 '18 at 9:00
It's
[Recipe].self, not [[Recipe]] and I forgot the try before PropertyListDecoder(). Answer updated.– vadian
Dec 30 '18 at 9:02
It's
[Recipe].self, not [[Recipe]] and I forgot the try before PropertyListDecoder(). Answer updated.– vadian
Dec 30 '18 at 9:02
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
I added the try part, I have written it the same way you have. but the error still gives the same thing. Cannot invoke 'decode' with an argument list of type '([[Recipe]], from: Data)'
– Tony Doubleman
Dec 30 '18 at 9:03
The error indicates that there are two pairs of square brackets around
Recipe. Actually there is only one pair.– vadian
Dec 30 '18 at 9:35
The error indicates that there are two pairs of square brackets around
Recipe. Actually there is only one pair.– vadian
Dec 30 '18 at 9:35
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
Would that be because the array that I am trying to store in UserDefaults is global? I have only one pair of square brackets around [Recipe].
– Tony Doubleman
Dec 30 '18 at 9:47
|
show 3 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.
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%2f53975223%2fis-there-a-way-to-unarchive-object-which-is-being-saved-in-userdefaults-using-un%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