NSUserDefaultsによる永続化

iosアプリを停止させても消したくない情報を永続化する方法を調べた。 永続化の方法としてはNSUserDefaults、NSKeyedArchiver、プロパティリスト、CoreDataなどの方法があるらしい。

CoreDataはちょっとしたデータの保存には大変すぎる。 NSKeyedArchiverはシリアライズしたデータをファイルとして保存する方法で、保存する場所を指定する必要がある。 プロパティリストはkey、valueを指定して.pistファイルに情報を保存する方法で、アプリの設定などを扱っていることが多い。

NSUserDefaultsは保存する場所の指定などが不要で、最も手軽そうだったので今回はこれを使う。

使い方

let userDefaults = NSUserDefaults.standardUserDefaults()


//データを保存する
self.userDefaults.setObject("hoge", forKey: "huga")

//データを取り出す
let authData = self.userDefaults.objectForKey("huga") as? String

かなり手軽にデータの保存ができるが上記のコードをそのまま使うと、キーや型をベタ書きすることになり管理がし難い。 ググってみたところ、wrapperを用意して使うのが良さそう。 データがある程度複雑ならプロパティリストやCoreDataを使用するべきだと思う。

また、NSUserDefaultsは消える恐れがあるらしいく、消えてもいいデータに限ってしか使えないようだ。 今回のケースでは問題なかったけど、アプリ中断時に開いていたページの情報とか、トークンのような揮発しても問題ないなものにしか使うべきじゃないのかもしれない。

UIImageをリサイズする

IOSアプリで画像を表示する時、画像サイズに依存せずにViewいっぱいに表示したい。
その際、縦長の画像が縦に押しつぶされた状態になるなど、画像が変にリサイズされて歪んでしまうのは避けたいというコード。

一旦リサイズしさらにトリミングするという処理をしているため、無駄が多いように思える。
もっといい方法がありそうだけ、swift初心者なので思いつかなかった。。。

func fixImageSize(image: UIImage, width: CGFloat, height: CGFloat) -> UIImage{
        let widthRatio = width / image.size.width
        let heightRatio = height / image.size.height
        
        let (resizeWidth, resizeHeight) = heightRatio > widthRatio ? (image.size.width * heightRatio, height):(width, image.size.height * widthRatio)
        
        let (x, y) = ((resizeWidth - width) / 2, (resizeHeight - height) / 2)
        
        let size: CGSize = CGSize(width: resizeWidth, height: resizeHeight)
        UIGraphicsBeginImageContext(size)
        image.drawInRect(CGRectMake(0, 0, resizeWidth, resizeHeight))
        let resizeImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        let trimRect  = CGRectMake(x, y, width, height)
        let trimRef   = CGImageCreateWithImageInRect(resizeImage.CGImage, trimRect)
        let trimImage = UIImage(CGImage: trimRef!)
        
        return trimImage
}