20220119 iOS 일일 개발일지 === ###### tags: `develop` User Defaults, KeyChain 사용하기 UserDefault : 사용자의 기본 데이터베이스 앱 실행 시 키-값 쌍을 지속적으로 저장 NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary **How to use** ```swift= UserDefaults.standard.set("loggedIn", forKey: "status") let status = UserDefaults.standard.string(forKey: "status") ``` User Defaults를 사용하면 간단한 사용자 설정(알림이나 설정 페이지에서 결정하는 사항) 등을 저장할 수 있고, 앱이 삭제될 때 함께 사라지는 데이터, UserDefaults로 저장하는 데이터는 plist에 저장된다. Keychain --- 왜 사용해야하는가? User 데이터를 보다 안전하게 보관할 수 있음. KeyChain item으로 패키징. KeyChain item은 데이터 자체와 함께 항목의 접근성을 제어하고, 검색하게 만들기 위해 공개적으로 표시되는 속성 집합을 제공 키 체인 서비스 : 디스크에 저장된 암호화된 데이터베이스인 키 체인에서 데이터를 암호화 및 저장을 처리함. 나중에 승인된 프로세스는 키 체인 서비스를 사용해 항목을 찾고 데이터를 해독한다. 사용하는 방법을 살펴보면 저장할 데이터와 속성 집합을 딕셔너리 형태의 Keychain Item으로 만들고, 사용 메소드 ```swift= // 데이터 저장 public func SecItemAdd( _ attributes: CFDictionary, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus // 데이터 읽기 public func SecItemCopyMatching( _ query: CFDictionary, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus // 데이터 수정 public func SecItemUpdate( _ query: CFDictionary, _ attributesToUpdate: CFDictionary) -> OSStatus // 데이터 삭제 public func SecItemDelete(_ query: CFDictionary) -> OSStatus ``` 사용자가 직접 제거하지 않는 이상 앱을 제거해도 남아 있음. 디바이스를 Lock할 경우, keyChain도 잠기고, 디바이스를 Unlock하면 keyChain도 풀린다. - KeyChain이 풀린 상태에서만 해당 item을 생서앟고, 저장한 어플리케이션에서만 접근이 가능하다. 인터넷용 아이디/비밀번호를 저장할 경우 kSecClassInternetPasword 인증서 저장할 경우 kSecClassCertificate 일반 비밀번호 저장할 경우 kSecClassGenericPassword Touch Event가 제대로 발생하지 않는 문제에 대한 해결 방법 ```swift= private lazy var buyButton: TradeButton = { let button = TradeButton(tradeType: .buy) button.addTarget(self, action: #selector(didTapBuyButton ), for: .touchUpInside) return button }() private lazy var sellButton: TradeButton = { let button = TradeButton(tradeType: .sell) button.addTarget(self, action: #selector(didTapSellButton), for: .touchUpInside) return button }() private lazy var wishButton: WishButton = { let button = WishButton(frame: .zero) button.addTarget(self, action: #selector(didTapWishButton), for: .touchUpInside) return button }() private lazy var tradeStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [buyButton, sellButton]) stackView.axis = .horizontal stackView.distribution = .fillEqually stackView.spacing = 5 return stackView }() private lazy var containerStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [wishButton, tradeStackView]) stackView.axis = .horizontal stackView.spacing = 10 stackView.backgroundColor = .white return stackView }() ``` 코드 내에서 stackView가 user의 event를 받도록 되어 있었음. 따라서 실제 이벤트는 내부 stackView에게 전달되고 있었음 참고 --- developer.apple.com/documentation/foundation/userdefaults https://kor45cw.tistory.com/285 Swift 개발 - Keychain 사용하여 데이터 저장하기 https://developerbee.tistory.com/56