JY-CONTENTS

JY

JY-CONTENTS
search

+

MENU

【Swift/ios】UserDefaults

【Swift/ios】UserDefaults

(DATE)

-

2017.10.04

(CATEGORY)

-

基本的な流れ

//インスタンスの生成
let userDefaults = UserDefaults.standard

//キーを「test」に指定して、文字列を保存
userDefaults.set("1234", forKey: "test")

//明示的な同期指示(キャッシュメモリからplist形式への保存)
userd.synchronize()

//「test」キーに対応するString型の保存された値を取り出す
let val = userDefaults.string(forKey: "test")

アプリ開発時の使い方

@IBOutlet weak var textField: UITextField!
    
@IBAction func tapActionButton(_ sender: AnyObject) {
   let userDefaults = UserDefaults.standard
   //保存
   userDefaults.set(textField.text, forKey: "test")
   userDefaults.synchronize()
}
    
override func viewDidLoad() {
    super.viewDidLoad()
    let userDefaults = UserDefaults.standard  
    //取り出し
    if let value = userDefaults.string(forKey: "test") {
        textField.text = value
    }
}

独自クラスを保存する

UserDefaultsはNSData型の保存をサポートしているので、独自クラスを一旦NSData型にすることでUserDefaultsに保存することができます。

シリアライズ

オブジェクトの内容をバイナリデータに変換すること。

シリアライズするためのクラス

NSKeyedArchiver

NSKeyedArchiverクラスに呼び出される独自クラス側に実装するメソッド

NSCodingプロトコルのencodeメソッド

public func encode(with aCoder: NSCoder)

NSKeyedArchiverクラスでのシリアライズ処理をする時は、独自クラス側に決められたメソッドを実装し、この実装したメソッドがNSKeyedArchiverクラスに呼び出されることになります。この決められたメソッドはNSCodingプロトコルのencodeメソッドです。

NSCodingプロトコル

独自クラスをUserDefaultsに保存するときは必ずNSCodingプロトコルを継承します。
それは、このプロトコルにシリアライズ、デシリアライズを行うメソッドが定義されているからです。
メソッドの引数はNSCoder型で、NSCoderクラスにはシリアライズ、デシリアライズに関するメソッド群が定義されています。
また、シリアライズの対象となるクラス(独自クラス)はNSObjectクラスを継承する必要がある。

※)厳密にはNSKeyedArchiverクラスがシリアライズ処理そのものを行うのではなく、呼び出された独自クラスに実装されているNSCodingプロトコルのencodeメソッド内で独自クラスのシリアライズ処理は行われます。
引数のNSCoderクラスのシリアライズに関するメソッドを用いて処理を行います。
NSKeyedArchiverクラスの役割はencodeメソッドの呼び出しです。
デシリアライズに関しても同じです。

class Myclass: NSObject, NSCoding{

   var valueString: String?
   //引数なしのイニシャライザを設定。引数なしでのインスタンスを生成しない場合はなくてもよい
   override init(){}

   //NSKeyedArchiverに呼び出されるエンコードメソッド
   func encode(with aCoder: NSCoder) {
      //引数で受け取ったNSCoderクラスにはシリアライズ、デシリアライズに
      //関するメソッド群が定義されている
      //キーを指定してオブジェクト(値)をエンコード(シリアライズ)
      aCoder.encode(valueString, forKey: "valueString")
   }

   //NSKeyedUnArchiverに呼び出されるデコードメソッド
   required init?(coder aDecoder: NSCoder) {
      //指定したキーの値をデコード(デシリアライズ)。今回は保存した値が文字列なのでstringにキャストし、
      //変数に収める
      valueString = aDecoder.decodeObject(forKey: "valueString") as? String
   }
}

※)プロトコルのイニシャライザをオーバーライドする時の修飾子は override ではなくrequired。

デシリアライズ

バイナリデータからオブジェクトを復元すること。

デシリアライズするためのクラス

NSKeyedUnArchiver

NSKeyedArchiverクラスに呼び出される独自クラス側に実装するメソッド

NSCodingプロトコルのinitメソッド
内容はシリアライズと同じ。

required init?(coder aDecoder: NSCoder)

実装コードは上記シリアライズ処理に記述。

メインのシリアライズとデシリアライズの処理

シリアライズ

NSKeyedArchiverクラスのarchivedDataメソッドにてシリアライズを行う。
※)厳密にはNSCodingプロトコルのencodeメソッドの呼び出し。

archivedData(withRootObject: シリアライズ対象のデータ)

デシリアライズ

NSKeyedUnarchiverクラスのunarchiveObjectメソッドにてデシリアライズを行う。
※)厳密にはNSCodingプロトコルのinitメソッドの呼び出し。

unarchiveObject(with: デシリアライズ対象のデータ)

使い方

//デシリアライズしたデータを変数に収める
let unarchiveData = NSKeyedUnarchiver.unarchiveObject(with: デシリアライズ対象のデータ)

アプリ開発時の使い方

※独自クラスを上記に記述

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        //UserDefaultsのインスタんすの生成
        let userDefaults = UserDefaults.standard
        //独自クラスのインスタンスを生成
        let data = MyClass()
        data.valueString = "test"
        

        //**************シリアライズ処理****************************************
        //シリアライズ対象データは独自クラスのMyClassのインスタンス
        let archiveData = NSKeyedArchiver.archivedData(withRootObject: data)
        //シリアライズしてNSData型になったデータを保存
        userDefaults.set(archiveData, forKey: "data")
        //更新
        userDefaults.synchronize()
        
        
        //**************デシリアライズ処理***************************************
        //キーを指定してデータをNSData型に変換して取り出す。
        //userDefaultsには最終的にはplist形式(xml)で保存されるため,
        //unarchiveObjectメソッドの引数の型がData型のためキャストする
        if let storedData = userDefaults.object(forKey: "data") as? Data{
            
            //取り出したデータをデシリアライズし、保存する前の型にキャストする
            if let unarchiveData = NSKeyedUnarchiver.unarchiveObject(with: storedData) as? MyClass{
                
                //取り出したデータ(MyClassクラスのインスタンス)のプロパティの文字列を表示させる
                if let valueString = unarchiveData.valueString {
                    //「test」を表示
                    print(valueString)
                }
                
            }
        }
        
}

NEW TOPICS

/ ニュー & アップデート

SEE ALSO

/ 似た記事を見る

JY CONTENTS UNIQUE BLOG

search-menu search-menu