티스토리 뷰

싱글톤패턴으로 UserDefaults 코드 수정

 

 

class UserDefaultsHelper {
    
    //인스턴스 생성방지
    private init() {}
    
    //인스턴스 생성
    static let shared = UserDefaultsHelper()
    
    let userDefaults = UserDefaults.standard
    
    let domain = Bundle.main.bundleIdentifier!
    
    //userdefaults 키 -> rawValue로 사용
    enum Keys: String {
        case name
        case tamagotchi
        case status
    }
    
    var name: String {
        get {
            return userDefaults.string(forKey: Keys.name.rawValue) ?? ""
        }
        set {
            userDefaults.set(newValue, forKey: Keys.name.rawValue)
        }
    }
    
    var tamagotchi: Data {
        get {
            if let tamaData = userDefaults.object(forKey: Keys.tamagotchi.rawValue) as? Data {
                return tamaData
            }
            return Data()
        }
        set {
            userDefaults.set(newValue, forKey: Keys.tamagotchi.rawValue)
        }
    }
    
    var status: Data {
        get {
            if let statusData = userDefaults.object(forKey: Keys.status.rawValue) as? Data {
                return statusData
            }
            return Data()
        }
        set {
            userDefaults.set(newValue, forKey: Keys.status.rawValue)
        }
    }
    
    //전체 지우는 메서드
    func removeAllContents() {
        userDefaults.removePersistentDomain(forName: domain)
    }
}

위의 UserDefaultsHelper를 이용해서 코드를 수정했음.

 

-> 기존에 생성하던 userDefaults 상수도 이미 클래스내에 선언되어있어 따로 선언할 필요 없어짐.

-> 문자열 하드코딩을 줄일 수 있음.

-> 옵셔널로 처리하지않아서 nil값을 받을 가능성을 없앰. 대신 기존의 nil로 따졌던 조건문은 수정이 필요

-> 코드가 훨씬 간결해짐

-> 메서드도 가능

데이터 가져오기
데이터 전체 삭제
데이터 저장

 

 

 

enum에 case대신 타입 프로퍼티로 선언

 

 

나중에 rawValue가 중복되는 일이 생길 수도 있으므로 일단 타입 프로퍼티로 바꿔보았음.

 

또한 rawValue를 안써도돼서 코드가 아주 살짝 줄어듦.

enum StoryboardName: String {
    
    case select = "Select"
    case detail = "Detail"
    case main = "Main"
    case setting = "Setting"
    case name = "Name"
    
}

위를 아래처럼

enum StoryboardName {

    static let select = "Select"
    static let detail = "Detail"
    static let main = "Main"
    static let setting = "Setting"
    static let name = "Name"
    
}

StoryboardName, CustomFont, ImageName, DetailViewButtonTitle 이렇게 총 네 가지의 열거형을 수정하였음.

 

 

 

Extension으로 identifier 프로토콜 채택

 

 

이전에 프로토콜을 채택해서 더 간단하긴 했지만 그래도 매번 뷰컨트롤러마다 변수를 만들어줘야했음.

 

extension안에 타입 프로퍼티로 채택하면 따로 변수를 만들지않아도 사용 가능.

extension UICollectionViewCell: IdentifierProtocol {
    static var reuseIdentifier: String {
        get {
            return String(describing: self)
        }
    }
}

위와 같이 ViewController, TableViewCell, CollectionViewCell에 모두 채택하여 reuseIdentifier를 작성해주었음.

따로 프로퍼티를 생성하지않아도 사용 가능.

 

 

 

프로토콜로 구조화

-> 멘토님이 말씀해주신 구조화가 이런 방법이 맞는지는 모르겠다.

 

 

뷰의 UI를 세팅하는 메서드가 뷰컨트롤러마다 사용되는 것 같아 프로토콜로 만들어보기로함.

 

하지만 메서드의 파라미터로 데이터를 받는 뷰컨트롤러도 있어서 파라미터를 이용하는 부분만 따로따로 작성하고 매개변수를 받지 않는 메서드로 만듦.

 

setUpButton메서드는 하나의 뷰컨트롤러에서만 쓰이길래 매개변수채로 가져옴.

 

아래와 같이 프로토콜을 만들어줌.

 

공통으로 사용되는 메서드가 없어서 전부 optional로 선언.

@objc protocol SetUpMethod {
    
    @objc optional func setUpCollectionView()
    @objc optional func setUpNavigationBar()
    @objc optional func setUpView()
    
    //MainViewController에서만 쓰이는 메서드인데 버튼 setup하는 메서드가 하나여서 매개변수와 같이 가져옴
    @objc optional func setUpButton(button: UIButton, outerView: UIView, lineView: UIView, textField: UITextField, placeholder: String, buttonTitle: String, buttonImage: String)
    
}

 

아래처럼 다른 모든 뷰컨트롤러에서도 SetUpMethod를 채택하고 각각 해당되는 메서드를 해당 뷰컨트롤러에서 구현해줌.

댓글
최근에 올라온 글
Total
Today
Yesterday