Swift 앱에서 로컬 데이터를 저장하는 방법은 무엇입니까?


148

현재 Swift에서 개발 된 iOS 앱을 개발 중이며 사용자가 만든 일부 콘텐츠를 장치에 저장해야하지만 사용자 콘텐츠를 장치에 저장 / 수신하는 간단하고 빠른 방법을 찾지 못하는 것 같습니다.

누군가 로컬 저장소를 저장하고 액세스하는 방법을 설명 할 수 있습니까?

아이디어는 사용자가 작업을 실행할 때 데이터를 저장하고 앱이 시작될 때 데이터를받는 것입니다.


환영합니다. 어떤 종류의 데이터를 저장하고 있습니까? 찾고자하는 예제를 제공하는 코드를 제공 할 수 있습니까? 감사.
Wez

1
저장 해야하는 데이터는 기본적으로 문자열 데이터입니다. 정말 간단하게 유지하려면 사용자가 앱을 다시 시작할 때받을 수있는 두 개의 문자열 값을 저장해야합니다.
Nicklas Ridewing

2
NSUserDefaults를 사용할 수 있습니다. 다음은 필요한 정보입니다 codingexplorer.com/nsuserdefaults-a-swift-introduction
bpolat

답변:


197

두 개의 문자열 만 저장하는 경우 가장 간단한 해결책 NSUserDefaults은 Swift 3에서이 클래스의 이름이 just로 바뀌는 것 UserDefaults입니다.

코드의 다른 곳에서 키를 재사용 할 수 있도록 전 세계 어딘가에 키를 저장하는 것이 가장 좋습니다.

struct defaultsKeys {
    static let keyOne = "firstStringKey"
    static let keyTwo = "secondStringKey"
}

스위프트 3.0, 4.0 및 5.0

// Setting

let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: defaultsKeys.keyOne)
defaults.set("Another String Value", forKey: defaultsKeys.keyTwo)

// Getting

let defaults = UserDefaults.standard
if let stringOne = defaults.string(forKey: defaultsKeys.keyOne) {
    print(stringOne) // Some String Value
}
if let stringTwo = defaults.string(forKey: defaultsKeys.keyTwo) {
    print(stringTwo) // Another String Value
}

스위프트 2.0

// Setting

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: defaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: defaultsKeys.keyTwo)

// Getting

let defaults = NSUserDefaults.standardUserDefaults()
if let stringOne = defaults.stringForKey(defaultsKeys.keyOne) {
    print(stringOne) // Some String Value
}
if let stringTwo = defaults.stringForKey(defaultsKeys.keyTwo) {
    print(stringTwo) // Another String Value
}

사소한 구성, 플래그 또는 기본 문자열보다 더 심각한 경우에는 일종의 영구 저장소를 사용해야합니다. 현재 인기있는 옵션은 Realm 이지만 SQLite 또는 Apple 자체의 CoreData 를 사용할 수도 있습니다 .


7
좋은 예입니다. 이것은 아마도 구조체 대신 열거 형이어야합니다.
팬 앤 스캔

3
열거 형의 이상한 구현입니다. 정적 상수가있는 경우 구조체 일 수도 있습니다.
Craig Grummitt 2016 년

1
이 코드는 잘못되었습니다. KVC 방법 setValue(_:forKey:)을 사용하여 데이터를 UserDefaults에 저장 하지 마십시오 . (Swift 3에서) 제공된 UserDefaults방법을 사용하십시오 set(_:forKey:).
rmaddy

Swift 3 코드를 업데이트했습니다. Swift 2 구문이 무엇인지 모르겠습니다.
rmaddy

@rmaddy 그대로 괜찮습니다.
Wez

57

NSUserDefaults를 사용한다고 말합니다.

처음 (앱 종료 후) 데이터 스토리지를 처음 구현할 때 온라인에서 읽은 모든 내용이 NSUserDefaults를 가리 켰습니다. 그러나 사전을 저장하고 싶었지만 가능한 한 고통 스럽습니다. 나는 유형 오류를 없애려고 몇 시간을 보냈습니다.

NSUserDefaults도 기능이 제한됩니다

더 읽어 보면 NSUserDefaults의 읽기 / 쓰기가 실제로 앱이 모든 것을 읽거나 쓰지 못하게하는 방법을 보여 주었으므로 효율적이지 않습니다. 그런 다음 배열 검색이 간단하지 않다는 것을 알게되었습니다. 문자열이나 부울을 몇 개 이상 저장하면 NSUserDefaults가 이상적이지 않다는 것을 깨달았습니다.

또한 확장 할 수 없습니다. 코딩 방법을 배우고 있다면 확장 가능한 방법을 배우십시오. 기본 설정과 관련된 간단한 문자열 또는 부울을 저장하는 데 NSUserDefaults 만 사용하십시오. Core Data를 사용하여 어레이 및 기타 데이터를 저장하십시오. 작은 것부터 시작하십시오.

업데이트 : 또한 Apple Watch 지원을 추가하면 또 다른 잠재적 고려 사항이 있습니다. 이제 앱의 NSUserDefaults가 Watch Extension으로 자동 전송됩니다.

핵심 데이터 사용

그래서 Core Data가 더 어려운 솔루션이라는 경고를 무시하고 읽기 시작했습니다. 세 시간 안에 나는 그것을 작동시켰다. 테이블 배열을 Core Data에 저장하고 앱을 다시 열면 데이터를 다시로드했습니다! 튜토리얼 코드는 쉽게 적응할 수 있었고 약간의 추가 실험만으로 제목과 세부 배열을 모두 저장할 수있었습니다.

따라서 NSUserDefault 유형 문제로 어려움을 겪고 있거나 문자열을 저장하는 것 이상이 필요한이 게시물을 읽는 사람이라면 코어 데이터를 가지고 한두 시간을 소비하는 것을 고려하십시오.

내가 읽은 튜토리얼은 다음과 같습니다.

http://www.raywenderlich.com/85578/first-core-data-app-using-swift

"핵심 데이터"를 확인하지 않은 경우

앱을 만들 때 "핵심 데이터"를 확인하지 않은 경우 앱을 추가 한 후 5 분만에 추가 할 수 있습니다.

http://craig24.com/2014/12/how-to-add-core-data-to-an-existing-swift-project-in-xcode/

http://blog.zeityer.com/post/119012600864/adding-core-data-to-an-existing-swift-project

핵심 데이터 목록에서 삭제하는 방법

Coredata Swift에서 데이터 삭제


6
Documents 디렉토리 또는 앱의 샌드 박스 디렉토리에있는 .plist 파일에 데이터를 저장하는 중간 단계가 있습니다.
Nicolas Miari

저는 초보자입니다. 소금 한알로이 질문을하세요.하지만 그 중간 정도입니까? NSUserDefaults는 실제로 p.list 파일이므로, 내가 읽은 내용에 따라 문서 디렉토리의 p.list 파일에 저장하는 것은 NSUserDefaults를 사용하는 것과 같습니다. 그 방법을 사용하지 않은 이유는 배열을 p.list에 저장하면 다른 유형으로 변환 한 다음 나중에 값을 복원 할 때 값을 다시 할당 할 때 값을 다시 할당 해야하는 것과 같은 추가 단계가 필요하다고 들었 기 때문입니다. p.list에서. 다시 말하지만, 지난 며칠 동안 나의 독서에 기초한 것입니다.
Dave G

배열을 .plist 파일에 저장하는 것은 매우 간단합니다 (계층 구조의 모든 객체는 배열, 문자열, 사전 또는 숫자 (사용자 정의 클래스 없음)
Nicolas Miari

동의하면 파일을 읽는 것이 전부 또는 아무것도 아니지만, 구조에 따라 데이터를 별도의 파일로 분할 할 수 있습니다. 그리고 CoreData는 적어도 마지막으로 확인했을 때 상당한 학습 곡선을 보였습니다.
Nicolas Miari

3
NSUserDefaults를 사용하여 환경 설정 (결과적으로 이름의 의미)을 저장하고, 지속적이고 민감한 데이터를 저장하는 키 체인, 매우 기본적인 앱 생성 데이터를 위한 .plist 파일의 사용자 정의 구성표 , 더 무거운 것을위한 CoreData .
Nicolas Miari

11

@bploathttp://www.codingexplorer.com/nsuserdefaults-a-swift-introduction/에 대한 링크 덕분에 좋아요

기본 문자열 저장에 대한 대답이 매우 간단하다는 것을 알았습니다.

let defaults = NSUserDefaults.standardUserDefaults()

// Store
defaults.setObject("theGreatestName", forKey: "username")

// Receive
if let name = defaults.stringForKey("username")
{
    print(name)
    // Will output "theGreatestName"
}

http://ridewing.se/blog/save-local-data-in-swift/에 요약했습니다.


9

NSCoding과 NSKeyedArchiver를 사용 하는 것은 너무 복잡 NSUserDefaults하지만 CoreData가 과도하게 사용되는 데이터에 대한 또 다른 훌륭한 옵션입니다 . 또한 파일 구조를보다 명시 적으로 관리 할 수있는 기회를 제공하므로 암호화를 사용하려는 경우 유용합니다.


7

Swift 4.0의 경우 더 쉬워졌습니다.

let defaults = UserDefaults.standard
//Set
defaults.set(passwordTextField.text, forKey: "Password")
//Get
let myPassword = defaults.string(forKey: "Password")

6

스위프트 3.0

세터 : 로컬 스토리지

let authtoken = "12345"
    // Userdefaults helps to store session data locally 
 let defaults = UserDefaults.standard                                           
defaults.set(authtoken, forKey: "authtoken")

 defaults.synchronize()

게터 : 로컬 스토리지

 if UserDefaults.standard.string(forKey: "authtoken") != nil {

//perform your task on success }

2
UserDefaults에 authtoken과 같은 smth를 저장해서는 안됩니다. 키 체인을 사용하십시오
BilalReffas

5

스위프트 3

UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")

KVC 방법을 사용하여 데이터를 저장하지 마십시오.
rmaddy

4

어떤 이유로 UserDefaults를 처리하지 않으려는 경우 NSKeyedArchiver 및 NSKeyedUnarchiver 옵션이 있습니다. 아카이버를 사용하여 객체를 파일로 저장하고 보관 된 파일을 원본 객체로로드합니다.

// To archive object,
let mutableData: NSMutableData = NSMutableData()
let archiver: NSKeyedArchiver = NSKeyedArchiver(forWritingWith: mutableData)
archiver.encode(object, forKey: key)
archiver.finishEncoding()
return mutableData.write(toFile: path, atomically: true)

// To unarchive objects,
if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
    let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
    let object = unarchiver.decodeObject(forKey: key)
}

위의 샘플 코드를 사용하여 로컬 저장소에 객체를 저장 /로드하는 간단한 유틸리티를 작성했습니다. 이걸보고 싶을 수도 있습니다. https://github.com/DragonCherry/LocalStorage


4

스위프트 5+

어떤 대답도 실제로 기본 내장 로컬 스토리지 기능을 자세히 다루지 않습니다. 문자열보다 훨씬 더 많은 것을 할 수 있습니다 .

기본 설정에서 데이터를 '얻는'애플 문서에서 바로 다음과 같은 옵션이 있습니다.

func object(forKey: String) -> Any?
//Returns the object associated with the specified key.

func url(forKey: String) -> URL?
//Returns the URL associated with the specified key.

func array(forKey: String) -> [Any]?
//Returns the array associated with the specified key.

func dictionary(forKey: String) -> [String : Any]?
//Returns the dictionary object associated with the specified key.

func string(forKey: String) -> String?
//Returns the string associated with the specified key.

func stringArray(forKey: String) -> [String]?
//Returns the array of strings associated with the specified key.

func data(forKey: String) -> Data?
//Returns the data object associated with the specified key.

func bool(forKey: String) -> Bool
//Returns the Boolean value associated with the specified key.

func integer(forKey: String) -> Int
//Returns the integer value associated with the specified key.

func float(forKey: String) -> Float
//Returns the float value associated with the specified key.

func double(forKey: String) -> Double
//Returns the double value associated with the specified key.

func dictionaryRepresentation() -> [String : Any]
//Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.

'설정'옵션은 다음과 같습니다.

func set(Any?, forKey: String)
//Sets the value of the specified default key.

func set(Float, forKey: String)
//Sets the value of the specified default key to the specified float value.

func set(Double, forKey: String)
//Sets the value of the specified default key to the double value.

func set(Int, forKey: String)
//Sets the value of the specified default key to the specified integer value.

func set(Bool, forKey: String)
//Sets the value of the specified default key to the specified Boolean value.

func set(URL?, forKey: String)
//Sets the value of the specified default key to the specified URL.

큰 데이터 세트가 아닌 환경 설정 과 같은 것을 저장하는 경우 완벽하게 훌륭한 옵션입니다.

이중 예 :

환경:

let defaults = UserDefaults.standard
var someDouble:Double = 0.5
defaults.set(someDouble, forKey: "someDouble")

점점 :

let defaults = UserDefaults.standard
var someDouble:Double = 0.0
someDouble = defaults.double(forKey: "someDouble")

getter 중 하나에 흥미로운 점은 dictionaryRepresentation 이며,이 편리한 getter는 데이터 유형에 관계없이 모든 데이터 유형을 가져 와서 문자열 이름으로 액세스하고 요청할 때 올바른 해당 데이터 유형을 제공 할 수있는 좋은 사전에 넣습니다. 'any' 형식이므로 다시 돌아옵니다. .

그에 따라 func set(Any?, forKey: String)and func object(forKey: String) -> Any?setter 및 getter를 사용하여 자신의 클래스와 객체를 저장할 수 있습니다 .

이것이 로컬 데이터를 저장하는 UserDefaults 클래스의 힘을 더 잘 나타내기를 바랍니다.

저장하고 얼마나 자주해야 얼마의 메모에서 Hardy_Germany는 이에 그에 좋은 답변했다 게시물을 , 여기에서 인용 한 것입니다

많은 사람들이 이미 언급했듯이 : .plist (예 : UserDefaults)에 데이터를 저장하는 SIZE 제한 (실제 메모리 제외)을 알지 못합니다. 따라서 HOW MUCH의 문제는 아닙니다.

실제 질문은 얼마나 자주 새 값 / 변경된 값을 작성해야하는지입니다. 그리고 이것은이 쓰기로 인한 배터리 소모와 관련이 있습니다.

iOS는 단일 값이 변경된 경우 데이터 무결성을 유지하기 위해 "디스크"에 물리적으로 쓰는 것을 피할 수 없습니다. UserDefaults와 관련하여 전체 파일이 디스크에 다시 쓰여집니다.

이렇게하면 "디스크"의 전원이 켜지고 오랫동안 전원이 켜진 상태로 유지되어 IOS가 저전력 상태가되지 않습니다.

게시물 에서 사용자 Mohammad Reza Farahani가 언급 한 다른 사항 은 userDefaults 의 비동기동기 특성입니다.

기본값을 설정하면 프로세스 내에서 동 기적으로 변경되고 영구 저장소 및 기타 프로세스와 비동기 적으로 변경됩니다.

예를 들어 프로그램을 저장하고 빠르게 닫으면 결과가 저장되지 않는 것을 알 수 있습니다. 이는 비동기 적으로 지속되기 때문입니다. 프로그램을 종료하기 전에 저장을 계획하는 경우 완료 할 시간을 주어이를 설명 할 수 있습니다.

어쩌면 누군가 의견에 공유 할 수있는 좋은 해결책이 있습니까?


0

NsUserDefaults는 작은 가변 크기 만 저장합니다. 많은 객체를 저장하려면 CoreData를 기본 솔루션으로 사용하거나 .save () 함수처럼 객체를 쉽게 저장할 수있는 라이브러리를 만들었습니다. SQLite를 기반으로합니다.

SundeedQLite

그것을 확인하고 의견을 말 해주세요

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.