---
# System prepended metadata

title: 20220119 iOS 일일 개발일지
tags: [develop]

---

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


