Is there a way to unarchive object which is being saved in userdefaults using...












0















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.










share|improve this question





























    0















    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.










    share|improve this question



























      0












      0








      0








      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.










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 30 '18 at 5:59









      vadian

      146k13157175




      146k13157175










      asked Dec 30 '18 at 4:13









      Tony DoublemanTony Doubleman

      31




      31
























          1 Answer
          1






          active

          oldest

          votes


















          0














          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 =
          }





          share|improve this answer


























          • 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











          • 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











          • 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













          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
          });


          }
          });














          draft saved

          draft discarded


















          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









          0














          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 =
          }





          share|improve this answer


























          • 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











          • 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











          • 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


















          0














          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 =
          }





          share|improve this answer


























          • 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











          • 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











          • 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
















          0












          0








          0







          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 =
          }





          share|improve this answer















          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 =
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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 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











          • 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





















          • 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











          • 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











          • 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




















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Mossoró

          Error while reading .h5 file using the rhdf5 package in R

          Pushsharp Apns notification error: 'InvalidToken'