标签:
本文介绍了在IOS中常见的几种保存数据的方式,以及相关的实现方法(基于swift)。
思维导图:
每个IOS程序有一套自己独立的文件系统,其路径以
/
开始, 这个文件系统成为应用程序沙盒
。每个应用程序只能在自己的沙盒内部读写文件,基本不可以去访问外部文件。所有的操作都要进行权限检测。
沙盒是一种安全机制,其核心是对IOS应用的操作进行权限检测。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// In Unix, ~ -> /User/User name/...
// fetch document file address.
var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, false)
let doucmentDirectory = paths[0] as String
print(doucmentDirectory)
var tempDirectory = NSTemporaryDirectory()
// manager file.
let fileManager = NSFileManager.defaultManager()
let DoucementDirectoryWithManager = fileManager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
print(DoucementDirectoryWithManager)
}
提供一个与系统默认设置进行交互的编程接口,用于保存,恢复应用的偏好设置,配置数据等等。
将数据对象存储到“默认系统”的地方,能够持久化。
是一个单例。
适合存储轻量级的存储数据。
@IBOutlet weak var TextField: UITextField!
// The unique object!
var Users = NSUserDefaults.standardUserDefaults()
@IBAction func DataSave(sender: UIButton) {
let text = TextField.text
// Just the database, with value-to-key, it can set the data.
// Each key is unique.
Users.setObject(text, forKey: "Text")
// Don‘t forget to sync!
Users.synchronize()
}
@IBAction func DataLoad(sender: UIButton) {
// get string value.
let text = Users.stringForKey("Text")
TextField.text = text
}
在自己的应用中建立的一组文件,利用它可以告诉设备中的“设置”应用。(特别是在偏好设置)
在Settings bundle里面可以给定一些特定类型的控件,并设置相应的键值对。(如果没有给出键值就不会显示。)(右键可以选择显示键值对。)
特别值得注意的是,在Text控件里面可以改为Child Pane
。这是一个子视图入口,需要在Settings bundle里面创建另一个plist
。直接创建是创建不了的,只能进入文件夹内部进行操作。(如下图)然后在File属性里面给出相应的文件名就可以访问了。
//
// ViewController.swift
// 数据持久化
//
// Created by 颜泽鑫 on 7/7/16.
// Copyright ? 2016 颜泽鑫. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// loadDefaults()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
// getUserDefaults()
}
@IBOutlet weak var TextField: UITextField!
// The unique object!
var Users = NSUserDefaults.standardUserDefaults()
@IBAction func DataSave(sender: UIButton) {
updateUserDefaults()
}
@IBAction func DataLoad(sender: UIButton) {
getUserDefaults()
}
/**
Load Settings.bundles information and put them into NSUserDefaults.
*/
func loadDefaults() {
/// Enter the Settings.bundle.
let SettingsBubble = NSBundle.mainBundle().pathForResource("Settings", ofType: "bundle")
if SettingsBubble == nil {
return
} else {
// enter the More plist file.
// pay attention to `/`.
// stringByAppendingString : append another stirng.
// the valid URL gap by `/`.
// in this file, the data is save as dictionary.
let root = NSDictionary(contentsOfFile: SettingsBubble!.stringByAppendingString("/More.plist"))
// By key, you can get the whole Array,
let preferences = root?.objectForKey("PreferenceSpecifiers") as! Array<NSDictionary>
let defaultToRegister = NSMutableDictionary(capacity: root!.count)
// visit the whole array, and put them together into `defaultToRegister`.
for preference in preferences {
let key = preference.objectForKey("Key") as! String?
if key != nil {
defaultToRegister.setValue(preference.objectForKey("DefaultValue"), forKey: key!)
}
}
// put the `defaultToRegister` into NSUserDefaults so that they can be load.
NSUserDefaults.standardUserDefaults().registerDefaults((defaultToRegister as NSDictionary) as! [String : AnyObject])
}
}
func getUserDefaults() {
// Because of having load info, you can easy get value by its key.
let Defaults = NSUserDefaults.standardUserDefaults()
TextField.text = Defaults.objectForKey("name_preferences") as? String
}
func updateUserDefaults() {
let Defaults = NSUserDefaults.standardUserDefaults()
Defaults.setBool(false, forKey: "enabled_preference")
// Don‘t forget to sync.
Users.synchronize()
}
}
这就类似于在C中做文件操作,只能完全地读入文件内信息,对于类似于Database的信息,仍然需要做特别的转换。(可以使用json文件,目前还没有找到合适的json库。)
@IBOutlet weak var TextField: UITextField!
// The unique object!
var Users = NSUserDefaults.standardUserDefaults()
@IBAction func DataSave(sender: UIButton) {
let text = TextField.text! as NSString
/**
* Write the info into file.
* Using error handling, too.
*/
do {
try text.writeToFile(getFilePath("data.txt"), atomically: true, encoding: NSUTF8StringEncoding)
} catch {
print("Can‘t save!")
return
}
}
@IBAction func DataLoad(sender: UIButton) {
let textFilePath = getFilePath("data.txt")
// Judge if the file exists.
if NSFileManager.defaultManager().fileExistsAtPath(textFilePath) {
/**
* Transfer the file info to NSString is `throws` functions.
* So it is neccessary to use error handling method.
*/
do {
let text = try NSString(contentsOfFile: textFilePath, encoding: NSUTF8StringEncoding)
TextField.text = text as String
} catch {
print("Can‘t load!")
}
} else {
print("File don‘t exist!")
}
}
/**
In this function, we will get the path of file.
- parameter filename: The file name you wanna load.
- returns: path
*/
func getFilePath(filename : String) -> String {
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var DocumentPath = path[0] as NSString
/**
* You still need to pay attention to add `/` before file name.
* So that you can interval the different component.
* @param "/"
*
* @return path
*/
DocumentPath = DocumentPath.stringByAppendingString("/")
return DocumentPath.stringByAppendingString(filename)
}
用于存储一些在通用文件保存中无法保存的类型,例如图片、视频等等
两个关键概念:
import Foundation
import UIKit
/// This is the data type which we wanna save.
class Person : NSObject, NSCoding {
var name = ""
var logos : UIImage!
override init() {
super.init()
}
/**
This method is neccessary which is used to get info
from the file.
*/
required init?(coder aDecoder: NSCoder) {
super.init()
name = aDecoder.decodeObjectForKey("name") as! String
logos = aDecoder.decodeObjectForKey("logo") as! UIImage
}
/**
This method is used to input info into the file.
*/
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: "name")
aCoder.encodeObject(logos, forKey: "logo")
}
}
//
// ViewController.swift
// 数据持久化
//
// Created by 颜泽鑫 on 7/7/16.
// Copyright ? 2016 颜泽鑫. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// loadDefaults()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
// getUserDefaults()
}
@IBOutlet weak var TextField: UITextField!
// The unique object!
@IBOutlet weak var logo: UIImageView!
@IBAction func DataSave(sender: UIButton) {
let text = TextField.text!
let logos = UIImage(named: "1")
let textPath = getFilePath("data.txt")
let person = Person()
person.name = text
person.logos = logos
/// Archive the `person` and then write it into the file.
let data = NSKeyedArchiver.archivedDataWithRootObject(person)
do {
try data.writeToFile(textPath, options: NSDataWritingOptions.AtomicWrite)
} catch {
print("Write error!")
}
}
@IBAction func DataLoad(sender: UIButton) {
let textPath = getFilePath("data.txt")
/// Unarchive the file to get `Person` info.
let person = NSKeyedUnarchiver.unarchiveObjectWithFile(textPath) as! Person
TextField.text = person.name
logo.image = person.logos
}
/**
In this function, we will get the path of file.
- parameter filename: The file name you wanna load.
- returns: path
*/
func getFilePath(filename : String) -> String {
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var DocumentPath = path[0] as NSString
/**
* You still need to pay attention to add `/` before file name.
* So that you can interval the different component.
* @param "/"
*
* @return path
*/
DocumentPath = DocumentPath.stringByAppendingString("/")
return DocumentPath.stringByAppendingString(filename)
}
}
Core Data是IOS对关系型数据库的一种封装,类似于编写Database一样保存数据。但是缺点是,相对比较麻烦,除非数据非常大,否则尽量不使用。
//
// ViewController.swift
// core
//
// Created by 颜泽鑫 on 7/8/16.
// Copyright ? 2016 颜泽鑫. All rights reserved.
//
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
/// Get AppDelegate object.
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
/// Get context which save the info of Company.
let context = appDelegate.managedObjectContext
/// This Request can execute all operation like, update, save or read.
let companyRequest = NSFetchRequest(entityName: "Company")
do {
let companyObjects = try context.executeFetchRequest(companyRequest) as! [NSManagedObject]
for object in companyObjects {
let name = object.valueForKey("name") as! String
let age = object.valueForKey("age") as! Int
let area = object.valueForKey("area") as! String
print("load Data name : \(name)")
print("load Data age : \(age)")
print("load Data area : \(area)")
}
} catch {
print("Fetch error!")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
在AppDelegate
里面还保存了很多相关的操作,可以仔细阅读相关注释。
// in AppDelegate
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application‘s managed object context before the application terminates.
let name = "stary"
let age = 20
let area = "ShenZhen"
let companyRequest = NSFetchRequest(entityName: "Company")
do {
let companyObjects = try managedObjectContext.executeFetchRequest(companyRequest) as! [NSManagedObject]
var Company : NSManagedObject?
/**
* Judge if there is Company object.
* If there isn‘t one, then you can initialize a new one.
*/
if companyObjects.count > 0 {
Company = companyObjects[0]
} else {
Company = NSEntityDescription.insertNewObjectForEntityForName("Company", inManagedObjectContext: managedObjectContext) as NSManagedObject
}
Company?.setValue(name, forKey: "name")
Company?.setValue(age, forKey: "age")
Company?.setValue(area, forKey: "area")
} catch {
print("Save error!")
}
self.saveContext()
}
标签:
原文地址:http://blog.csdn.net/stary_yan/article/details/51862529