[Swift] UserDefault로 localData 저장 / 한계점
1. UserDefault를 사용하기 위해 완전히 새로운 객체 생성
let defaults = UserDefaults.standard
2. 업데이트 된 항목 배열을 UserDefaults에 저장 할 수 있다.
self.defaults.set(self.itemArray, forKey: "TodoListArray")
<나같은 경우에는 add버튼을 눌렀을 때 UIAlert로 입력받은 값을 defaults에 저장>
@IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
var textField = UITextField() // alertTextField를 캐치해서 전역변수에 할당
let alert = UIAlertController(title: "Add New Todoey Item", message: "", preferredStyle: .alert)
let action = UIAlertAction(title: "Add Item", style: .default) { (action) in
self.itemArray.append(textField.text!) // 여기까지 하면 array에 추가 안됨..
//버튼 눌렀을 때 defaults에 저장
self.defaults.set(self.itemArray, forKey: "TodoListArray")
self.tableView.reloadData() // 얘까지 해줘야 array에 추가가 댐
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Create new Item"
textField = alertTextField
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
// UserDefaults는 plist 파일에 저장되므로 입력하는 모든 것이 key-value로 들어가기 때문에
항목을 검색하는 데에는 key가 필요하다
(여기까지 마치고 시뮬레이터를 돌려서 Additem을 해주면 TableView에 나타나지 않는다)
실제로 additem이후
3. defaults에 저장되는 값을 보기 위해 앱이 실행되는 샌드박스의 파일 경로와 시뮬레이터의 ID를 가져와야 함.
(1) Userdefaults 경로 검색
appdelegate-> didFinishLaunchingWithOptions에서
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//*** Override point for customization after application launch.
print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as String)
return true
}
경로 검색을 해주면 아래와 같이 print되는데,
시뮬레이터 ID를 가져와서
경로를 파인더에서 열어주면
실제로 plist파일이 있고,
key-value형태로 저장되고 있음을 알 수 있다.
이것이 실제로 저장되고 있음에도 불구하고, tableview에 보이지 않는 까닭은
실제 저장돼있는 이 key-value를 호출하지 않았기 때문이다.
4. viewdidload에 item Array를 가져오면
override func viewDidLoad() {
super.viewDidLoad()
if let items = defaults.array(forKey: "TodoListArray") as? [String] {
itemArray = items
}
}
defaults에 저장된 array가 나옴을 알 수 있다.
<viewcontroller 코드>
class TodoListViewController: UITableViewController {
var itemArray = ["Hi", "Just Do it", "Home Gym"]
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
if let items = defaults.array(forKey: "TodoListArray") as? [String] {
itemArray = items
}
}
하지만 하드코딩된 array정도는 가능하지만
커스텀 개체의 배열을 저장하는 데에 있어서는
UserDefaults는 적합하지 않다.
예를들어 MVC로 모델에
Arrary를 커스텀 해서 저장하려는 경우
다음과 같은 에러가 뜬다.
뿐만 아니라 데이터 저장 하기위해 전체 데이터를 다 로드해와야 하는 비효율 적인 친구이기 때문에
UserDefault보다는, NSCoder를 사용한다.