0

I have an array that stores a custom class that has been encoded so it can be saved to NSUserDefaults. Its based off tableView cells with a favorite button, every time the favorite button is pressed its saved to a local array then saved to NSUserDefaults. The issue is if the favorite button is pressed multiple times, multiple copies of that tableView cell will be saved to NSUserDefaults. Here is my code to save the data. I tried checking to see if the "savedFavorite" already exists in the array but since it has been encoded its a different encode value each time so it doesn't look like a duplicate:

 let myDefaults = NSUserDefaults.standardUserDefaults()
  let savedShow1 = "savedShow1"
  var savedFavorite: TvShowInfo!
  var savedFavoriteArray:[TvShowInfo] = []

  @IBAction func saveShow(sender: UIButton) {

    //accessing current point of tableView Cell
    let location: CGPoint = sender.convertPoint(CGPointZero, toView: self.tvShowTableView)
    let indexPath: NSIndexPath = self.tvShowTableView.indexPathForRowAtPoint(location)!
    let searchTermsData = myDefaults.objectForKey(savedShow1) as? NSData

    //accessing previously saved info so as not to overwrite it
    if searchTermsData?.length > 0 {
    let searchTermsArray = NSKeyedUnarchiver.unarchiveObjectWithData(searchTermsData!) as? [TvShowInfo]

    self.savedFavoriteArray = searchTermsArray!
    }

    if searchBarActive {
      savedFavorite = filteredShowSearchResults[indexPath.row]
    } else {
      savedFavorite = showArray[indexPath.row]
    }

      if savedFavoriteArray.contains(savedFavorite) {
        print("Item already in array")
      } else {
        savedFavoriteArray.append(savedFavorite)
   }

    let savedData = NSKeyedArchiver.archivedDataWithRootObject(savedFavoriteArray)
    myDefaults.setObject(savedData, forKey: savedShow1)
    myDefaults.synchronize()
  } 

Here is my custom class:

class TvShowInfo: NSObject, NSCoding {

  var poster: String
  var title: String
  var id: NSNumber

 init(poster: String, title: String, id: NSNumber) {

    self.poster = poster
    self.title = title
    self.id = id

  }

  // MARK: - comply wiht NSCoding protocol

  func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(poster, forKey: "poster")
    aCoder.encodeObject(title, forKey: "title")
    aCoder.encodeObject(id, forKey: "id")
  }

  required convenience init?(coder aDecoder: NSCoder) {

    // decoding could fail, for example when no Blog was saved before calling decode
    guard let unarchivedPoster = aDecoder.decodeObjectForKey("poster") as? String,
          let unarchivedTitle =  aDecoder.decodeObjectForKey("title") as? String,
          let unarchivedId = aDecoder.decodeObjectForKey("id") as? NSNumber

    else {
        // option 1 : return an default Blog
      self.init(poster: "unkown", title:"unkown", id: 0)
      return
    }

    // convenience init must call the designated init
    self.init(poster: unarchivedPoster, title: unarchivedTitle, id: unarchivedId)
  }
}
SwiftyJD
  • 5,257
  • 7
  • 41
  • 92
  • I think a better way to go about doing this is to remove the favorite from the array when it is "un-favorited"... then you just find that one item in the array that matches and remove it. – MSU_Bulldog Mar 22 '16 at 19:52
  • Thats a good idea, the problem is when thy press the favorite button multiple times, it will keep adding the cell info into the array before it can be "un-favorited". – SwiftyJD Mar 22 '16 at 19:58
  • One way to do it is to keep a copy of the array that isn't encoded, then it will be simple to check if it has already been favorited. – MSU_Bulldog Mar 22 '16 at 20:03
  • It's the custom class that is encoded, it doesn't it automatically. It's posted as part of the question. – SwiftyJD Mar 22 '16 at 20:06
  • I can see your question........... Just check if the same TVShowInfo object exists in SavedFavoriteArray, and if so remove it when you un-favorite – MSU_Bulldog Mar 22 '16 at 20:10
  • Whoops, didn't mean to come off as rude. I tried that by using this : if savedFavoriteArray.contains(savedFavorite) { print("Item already in array") } else { savedFavoriteArray.append(savedFavorite) } – SwiftyJD Mar 22 '16 at 20:13
  • But it didn't work because the TVShowInfo is encoded. – SwiftyJD Mar 22 '16 at 20:13
  • You could extend Array where Generator.Element is a TvShowInfo type and overload == – Eppilo Mar 22 '16 at 21:17

1 Answers1

0

You can also convert your array to set (NSSet), and your array will be free from duplicates right away. See this post: Set operations (union, intersection) on Swift array?

Community
  • 1
  • 1
Tom Tallak Solbu
  • 559
  • 6
  • 20