Conforming to NSCoding

1.8k views Asked by At

I cannot for the life of me figure out why I am getting the error that this class does not conform to NSCoding protocols. Maybe another set of eyes would help. I have tried to add comments to make it clear what each func is doing.

import Foundation
import UIKit

class Search: NSObject, NSCoding {

// Global Variables
var articlePicture: UIImage!
var articleTitle: String

// MARK: Public Init
init(articlePicture: UIImage, articleTitle: String) {
    self.articlePicture = articlePicture
    self.articleTitle = articleTitle
}

// Required NSCoding Protocol
required convenience init?(coder decoder: NSCoder) {
    guard let articlePicture = decoder.decodeObject(forKey: "articlePicture") as? UIImage,
        let articleTitle = decoder.decodeObject(forKey: "articleTitle") as? String
        else { return nil }

    self.init(
        articlePicture: articlePicture,
        articleTitle: articleTitle
    )
}

// Required NSCoding Protocal
func encodeWithCoder(coder: NSCoder) {
    coder.encode(self.articlePicture, forKey: "articlePicture")
    coder.encode(self.articleTitle, forKey: "articleTitle")
}

// Initialize [Search]
static var searches = [Search]()

static func getSearches() -> [Search]{
    return searches
}

static func setSearch(search: Search){
    searches.append(search)
}

// NSUserDefaults Searches Array funcs
static func saveSearches(){
    let searchData = NSKeyedArchiver.archivedData(withRootObject: searches)
    UserDefaults.standard.set(searchData, forKey: "searches")
}

static func loadSearches() -> [Search]{
    let searchData = UserDefaults.standard.object(forKey: "searches") as? NSData

    if let searchData = searchData {
        searches = (NSKeyedUnarchiver.unarchiveObject(with: searchData as Data) as? [Search])!
        return searches
    }
    return searches
}
}
2

There are 2 answers

0
Code Different On BEST ANSWER

Tips: press Cmd + 4 to open the Issue Navigator and Xcode will tell you more details.

In Swift 3, the encoding function has changed:

func encodeWithCoder(coder: NSCoder) {
    // Swift 2 and older
}

func encode(with coder: NSCoder) {
    // Swift 3
}

Change the method's signature and you should be fine

5
Jeroen Bakker On

In Swift 4 there is another way to encode/decode classes. Now you'll only have to conform to the protocol Codable. No more need to write all your encode and decodes and it supports classes without NSObject & enums & structs.

final class Search: Codable {

}

For more information, read https://developer.apple.com/documentation/swift/codable