본문 바로가기

iOS/iOS

iOS) NSCoding과 Archive를 통한 데이터 저장 - (2)

enum type archive

처음에 enum 타입을 통으로 encode했더니 에러가 발생하였다. archive할 때 화나는 점이 encode 하거나 decode할 때 따로 확인하지 않으면 에러가 발생하지 않는다는 것이다.

unit test를 생활화하자!

아무 에러없이 돌아가서 문제가 있는지 모르다가 멀티 씬을 적용했을 때 데이터가 초기화 되길래 하나씩 살펴보니 enum에서 문제가 있었다.

Convert rawValue to enum

enum의 rawvalue인 String 타입으로 encode한 다음 decode할 때 해당 스트링에 매칭되는 enum 값을 찾도록 하였다.

enum ProcessedType: String {
    case processed = "processed", lowFatProcessed = "low-fat processed", dairy = "dairy"

    static func matched(with: String) -> ProcessedType {
        switch with {
        case ProcessedType.processed.rawValue:
           return ProcessedType.processed
        case ProcessedType.lowFatProcessed.rawValue:
           return ProcessedType.lowFatProcessed
        case ProcessedType.dairy.rawValue:
           return ProcessedType.dairy
        default: return ProcessedType.dairy
        }
    }
}

전체 코드

class Milk: Beverage {
    let farmCode: String
    let processedType: ProcessedType

    init(brand: String,
         capacity: Int,
         price: Int,
         name: String,
         shelfLife: Int,
         calorie: Int,
         farmCode: String,
         processedType: ProcessedType)
    {
        self.farmCode = farmCode
        self.processedType = processedType
        super.init(brand: brand, capacity: capacity, price: price, name: name, shelfLife: shelfLife, calorie: calorie)
    }

    required init?(coder: NSCoder) {
        guard let farmCode = coder.decodeObject(forKey: "farmCode") as? String,
            let processedType = coder.decodeObject(forKey: "processedType") as? String else {
                return nil
        }
        self.farmCode = farmCode
        self.processedType = .matched(with: processedType)
        super.init(coder: coder)
    }

}

extension Milk {
    enum ProcessedType: String {
        case processed = "processed", lowFatProcessed = "low-fat processed", dairy = "dairy"

        static func matched(with: String) -> ProcessedType {
            switch with {
            case ProcessedType.processed.rawValue:
               return ProcessedType.processed
            case ProcessedType.lowFatProcessed.rawValue:
               return ProcessedType.lowFatProcessed
            case ProcessedType.dairy.rawValue:
               return ProcessedType.dairy
            default: return ProcessedType.dairy
            }
        }
    }
}

extension Milk {
    override func encode(with coder: NSCoder) {
        super.encode(with: coder)
        coder.encode(self.farmCode, forKey: "farmCode")
        coder.encode(self.processedType.rawValue , forKey: "processedType")
    }
}