分类 ios数据持久化 下的文章

CoreData基本使用

里面的代码都是在xcode已经设置好的前提下进行的,怎么在xcode中添加model之类的,就不记录了,在这里记录下代码

//
//  ViewController.swift
//  CoreData基本使用
//
//  Created by admin on 16/3/14.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
import CoreData
class ViewController: UIViewController {
    lazy var dbFilePath:String = {
        // 数据库保存的路径,这里是设置的沙盒的缓存文件
        // let temp = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! as String)/testdb.sqlite"
        // 数据库的保存路径,方便查看,所以写了个固定的目录
        let temp = "/Users/admin/sqllite/testdb.sqlite"
        return temp
    }()
    lazy var fileDirectory:String = {
        // 数据库保存的路径,这里是设置的沙盒的缓存文件
        // let temp = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! as String)/"
        // 数据库的保存路径,方便查看,所以写了个固定的目录
        let temp = "/Users/admin/sqllite/"
        return temp
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
//        self.setContext()
        self.setContextWithModelName("UserModel")
        self.insertGroup()
    }
    // 根据模型设置上下文,setContext方法会把所有的模型的表保存在同一个数据库文件中,这里可以根据那个传递的模型名称分开保存
    func setContextWithModelName(modelName:String)
    {
        let context = NSManagedObjectContext()
        let path = NSBundle.mainBundle().pathForResource(modelName, ofType: "momd")
        let model = NSManagedObjectModel(contentsOfURL: NSURL(fileURLWithPath: path!))
        let story = NSPersistentStoreCoordinator(managedObjectModel: model!)
        let savePath = "\(self.fileDirectory)\(modelName).sqlite"
        let _ = try? story.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL(fileURLWithPath: savePath), options: nil)
        context.persistentStoreCoordinator = story
        self.context = context
    }
    // 根据分组查询用户
    func selectUserWithGroup()
    {
        let request = NSFetchRequest(entityName: "Group")

        let pre = NSPredicate(format: "name = %@", argumentArray: ["管理员"])
        request.predicate = pre

        let groups:[Group]? = try? self.context?.executeFetchRequest(request) as! [Group]

        let requesUser = NSFetchRequest(entityName: "User")
        // 设置查询条件
        let preUser = NSPredicate(format: "group = %@", argumentArray: [groups![0]])
        requesUser.predicate = preUser

        let users:[User]? = try? self.context?.executeFetchRequest(requesUser) as! [User]

        for user in users!
        {
            print("用户名:\(user.name)")
            print("密码:\(user.password)")
            print("年龄:\(user.age)")
            // 这个字断是一个对象,但是需要转一下,有点麻烦啊,不知道有没有更好的方法
            let temp = user.group as! Group
            print("分组:\(temp.name)")
            print("*******************")
        }

    }
    func insertUser()
    {
        /**
        let num = 40000
        var sum = 0
        for var i = 0; i < num;i++
        {
            sum += i
        }
        print(sum)
        */
        let request = NSFetchRequest(entityName: "Group")
        // 获得所有分组
        let groups:[Group]? = try? self.context?.executeFetchRequest(request) as! [Group]

        let num = 100
        // 循环插入100个小芳
        for var i = 0; i < num;i++
        {
            let user:User = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: self.context!) as! User
            user.name = "小芳\(arc4random_uniform(100000))"
            user.age = NSNumber(unsignedInt: arc4random_uniform(100000))
            user.password = "\(arc4random_uniform(999999999))"
            user.group = groups?[Int(arc4random_uniform(UInt32((groups?.count)!)))]
            let _ = try? self.context?.save()
        }
    }
    // 插入关联表数据,这里是用户分组表
    func insertGroup()
    {
        let groupA:Group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext: self.context!) as! Group
        groupA.name = "管理员"
        let groupB:Group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext: self.context!) as! Group
        groupB.name = "游客"
        let _ = try? self.context?.save()
    }

    // 按条件查询
    func select()
    {
        let request = NSFetchRequest(entityName: "User")
        // 查询出在18岁和24岁之间的小芳
//        let pre = NSPredicate(format: "age <= %@ and age >= %@", argumentArray: [24,18])
        // 查询出名字中包含 22 的小芳
        let pre = NSPredicate(format: "name like %@", argumentArray: ["*22*"])

        request.predicate = pre

        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]
        // 输出
        for user in users!
        {
            print("名字:\(user.name)")
            print("密码:\(user.password)")
            print("年龄:\(user.age)")
            print("***********")
        }
    }
    // 修改
    func update()
    {
        // 修改年龄
        // 1.查找到要删除的对象
        let request = NSFetchRequest(entityName: "User")

        // 条件,age 小于等于 0
        let pre = NSPredicate(format: "age <= %@", argumentArray: [0])

        request.predicate = pre;

        // 2.先读取出用户
        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]
        // 改成 18
        for user in users!
        {
//            self.context?.deleteObject(user)
            user.age = 18
            // [self.context deleteObject:emp];
        }

        // 3.用context同步下数据库
        //所有的操作暂时都是在内存里,调用save 同步数据库
        let _ = try? self.context?.save()
    }
    // 删除
    func delete()
    {
        // 删除zhangsan
        // 1.查找到要删除的对象
        let request = NSFetchRequest(entityName: "User")

        // 条件,age字段等于 15089 的
        let pre = NSPredicate(format: "age=%@", argumentArray: [15089])

        request.predicate = pre;

        // 2.删除zhangsan
        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]

        for user in users!
        {
            self.context?.deleteObject(user)
            // [self.context deleteObject:emp];
        }

        // 3.用context同步下数据库
        //所有的操作暂时都是在内存里,调用save 同步数据库
        let _ = try? self.context?.save()
    }
    // 添加数据
    func insert()
    {
        for var i = 0;i < 100;i++
        {
            // 创建模型对象
            let user:User = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: self.context!) as! User
            // 设置模型属性
            user.name = "小芳\(rand())"
            user.password = "\(rand())"
            user.age = NSNumber(int: rand())
            //保存 - 通过上下文操作
            if (try? self.context?.save()) == nil
            {
                print("error")
            }
            else
            {
                print("ok")
            }
        }
    }
    // 所有的操作都需要上下文
    var context:NSManagedObjectContext?
    // 获得上下文
    func setContext()
    {
        // 1.上下文 关联UserModel.xcdatamodeld 模型文件
        let context = NSManagedObjectContext()

        // 关联模型文件

        // 创建一个模型对象
        // 传一个nil 会把 bundle 下的所有模型文件(xcdatamodeld后缀的文件) 关联起来
        let model = NSManagedObjectModel.mergedModelFromBundles(nil)

        // 持久化存储调度器
        let store = NSPersistentStoreCoordinator(managedObjectModel: model!)

        // 数据库保存的路径
        let fielPath = self.dbFilePath

        //
        let res = try? store.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL(fileURLWithPath: fielPath), options: nil)

        if res != nil
        {
            context.persistentStoreCoordinator = store
        }
        // 完成上下文的初始化
        self.context = context;
    }
}

FMDB的基本使用

//
//  FMDBTestController.swift
//  微博项目
//
//  Created by zhang on 16/3/13.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class FMDBTestController: UIViewController {
    var queue:FMDatabaseQueue?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        // 拼接文件名
        let filePath = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!)database.sqlite"
        print(filePath)
        self.queue = FMDatabaseQueue(path: filePath)

        // Do any additional setup after loading the view.
    }
    @IBAction func createTable(sender: AnyObject) {
        let sql = "create table if not exists t_user (id integer primary key autoincrement,name text,phone text);"
        // 创建数据库表
        // 提供了一个多线程安全的数据库实例
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })

    }

    @IBAction func insert(sender: AnyObject) {
        let sql = "insert into t_user (name,phone) values (?,?)"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: ["\(rand())","\(rand())"])
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func deleteTest(sender: AnyObject) {
        let sql = "DELETE FROM t_user "
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func update(sender: AnyObject) {
        let sql = "UPDATE t_user SET name = '2222222'"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func selectTest(sender: AnyObject) {
        let sql = "select * from t_user;"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let res:FMResultSet? = database.executeQuery(sql, withArgumentsInArray: nil)
            var arr:NSMutableArray = NSMutableArray()
            if res != nil
            {
                while(res!.next())
                {
                    let dic:NSDictionary = ["name":"\((res?.intForColumn("name"))!)","phone":(res?.stringForColumn("phone"))!,"id":(res?.stringForColumn("id"))!]
                    arr.addObject(dic)
                }
            }

            print(arr)
        })
    }
}

sqlite3的基本使用

使用之前先倒入sqlite3

//
//  ViewController.swift
//  数据库
//
//  Created by zhang on 16/3/13.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
class ViewController: UIViewController {
    var db:COpaquePointer = COpaquePointer()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.openDataBase()
        // Do any additional setup after loading the view, typically from a nib.
    }
    func openDataBase()
    {
        // 拼接文件名
        let filePath = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!)database.sqlite"
        print(filePath)
        // 打开数据库
        if (sqlite3_open(filePath, &self.db) == SQLITE_OK) {
            print("打开成功");
        }else{
            print("打开失败");
        }
    }
    func execute(sql:String)->Bool
    {
        var flag:Bool
        if (sqlite3_exec(self.db, sql, nil, nil, nil) == SQLITE_OK) {
            flag = true;
        }else{
            flag = false;
        }
        return flag;
    }
    func query(sql:String)->[NSMutableArray]
    {
        // 1. 准备语句
        var stmt: COpaquePointer = nil
        /**
        1. 数据库句柄
        2. SQL 的 C 语言的字符串
        3. SQL 的 C 语言的字符串长度 strlen,-1 会自动计算
        4. stmt 的指针
        5. 通常传入 nil
        */
        var data:[NSMutableArray] = []
        if sqlite3_prepare_v2(self.db, sql, -1, &stmt, nil) == SQLITE_OK {
            // 单步获取SQL执行的结果 -> sqlite3_setup 对应一条记录
            while sqlite3_step(stmt) == SQLITE_ROW {
                // 获取每一条记录的数据
                data.append(recordData(stmt))
            }
        }
        return data
    }
    ///  获取每一条数据的记录
    ///
    ///  :param: stmt prepared_statement 对象
    func recordData(stmt: COpaquePointer)->NSMutableArray
    {
        // 获取到记录
        let array = NSMutableArray()
        let count = sqlite3_column_count(stmt)
        print("获取到记录,共有多少列 \(count)")
        // 遍历每一列的数据
        for i in 0..<count {
            let type = sqlite3_column_type(stmt, i)
            // 根据字段的类型,提取对应列的值
            switch type {
            case SQLITE_INTEGER:
                print("整数 \(sqlite3_column_int64(stmt, i))")
                array.addObject("\(sqlite3_column_int64(stmt, i))")
            case SQLITE_FLOAT:
                print("小树 \(sqlite3_column_double(stmt, i))")
                array.addObject(sqlite3_column_double(stmt, i))
            case SQLITE_NULL:
                print("空 \(NSNull())")
            case SQLITE_TEXT:
                let chars = UnsafePointer<CChar>(sqlite3_column_text(stmt, i))
                let str = String(CString: chars, encoding: NSUTF8StringEncoding)!
                array.addObject(str)
                print("字符串 \(str)")
            case let type:
                print("不支持的类型 \(type)")
            }
        }
        return array
    }
    @IBAction func createDataBase(sender: AnyObject) {

    }
    @IBAction func createTable(sender: AnyObject) {
        let sql = "create table if not exists t_user (id integer primary key autoincrement,name text,phone text);"
        if self.execute(sql)
        {
            print("执行成功")
        }
        else
        {
            print("执行成功")
        }
    }

    @IBAction func insert(sender: AnyObject) {
        let sql = "insert into t_user (name,phone) values ('\(rand())','\(rand())')"
        if self.execute(sql)
        {
            print("执行成功")
        }
        else
        {
            print("执行成功")
        }
    }
    @IBAction func deleteTest(sender: AnyObject) {
        let sql = "DELETE FROM t_user "
        if self.execute(sql)
        {
            print("执行成功")
        }
        else
        {
            print("执行成功")
        }
    }
    @IBAction func update(sender: AnyObject) {
        let sql = "UPDATE t_user SET name = '2222222'"
        if self.execute(sql)
        {
            print("执行成功")
        }
        else
        {
            print("执行成功")
        }
    }
    @IBAction func selectTest(sender: AnyObject) {
        let sql = "select * from t_user;"
        print(self.query(sql))
    }
}

swift数据持久化的方式

之前有一篇文章,是说沙盒文件读写的,但是不详细,这个详细的记录下
数据持久化的方式分为几种,

1.plist
//
//  ViewController.swift
//  持久化数据-ns
//
//  Created by admin on 16/1/19.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    let filePath = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!)/data.plist"
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    // 保存数据方法
    @IBAction func saveData(sender: AnyObject) {
        // 字串保存,NSString类型和这个保存方式一致
        let string:String = "string"
        _ = try? string.writeToFile(filePath, atomically: true, encoding: NSUTF8StringEncoding)
        // 数组保存,NSArray类型才可以
        let array:NSArray = [1,2,3]
        array.writeToFile(filePath, atomically: true)
        // 字典保存,NSDictionary才可以
        let dictionary:NSDictionary = ["dic":"aaa"]
        dictionary.writeToFile(filePath, atomically: true)

    }
    // 读取数据方法
    @IBAction func readData(sender: AnyObject) {
        let string:String! = try? String(contentsOfFile: filePath)
        // 数组读取
        let array = NSArray(contentsOfFile: filePath)
        // 字典读取
        let dictionary = NSDictionary(contentsOfFile: filePath)
        print(dictionary)
    }



}
2.系统偏好设置
//
//  ViewController.swift
//  持久化数据-偏好设置
//
//  Created by admin on 16/1/19.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.saveData()
        self.readData()
    }
    func saveData()
    {
        // 获得 NSUserDefaults 对象
        let def = NSUserDefaults.standardUserDefaults()
        // 设置值,还可以设置其它值,就不一一尝试了
        def.setObject("test", forKey: "def")
        // 设置值之后,并不是立即保存到文件的,这里需要保存下
        def.synchronize()
    }
    func readData()
    {
        // 先获取对象
        let def = NSUserDefaults.standardUserDefaults()
        // 再获取值
        print(def.objectForKey("def"))
    }
}
3.NSCoding,自定以对象存储的时候注意实现协议的方法
//
//  ViewController.swift
//  数据持久化-NSCoding
//
//  Created by admin on 16/1/19.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    let filePath = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!)/data.plist"
    override func viewDidLoad() {
        super.viewDidLoad()
        let arr:Array = [1,2,3]
        // 遵循了NSCoding协议并实现了 编码方法和构造方法才能使用
        // 写入,就不一一测试了
//        NSKeyedArchiver.archiveRootObject(arr, toFile: filePath)
        // 读取
//        print(NSKeyedUnarchiver.unarchiveObjectWithFile(filePath))
        // 自定义单个对象的读写
        let dog = Dog(name: "dog")
        // 写入
        NSKeyedArchiver.archiveRootObject(dog, toFile: filePath)
        // 读取
        let encodeDog = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! Dog
        print(encodeDog.name)

        // 存放多个对象到同一个文件中时使用 NSMutableData
        // 写入
        // 初始化多个对象
        let dogA = Dog(name: "dogA")
        let dogB = Dog(name: "dogB")
        // 初始化 Data 对象
        let dataEncoding = NSMutableData()
        // 初始化 archiver 对象
        let archiverEncoding = NSKeyedArchiver(forWritingWithMutableData: dataEncoding)
        // 编码对象
        archiverEncoding.encodeObject(dogA, forKey: "dogA")
        archiverEncoding.encodeObject(dogB, forKey: "dogB")
        // 结束编码
        archiverEncoding.finishEncoding()
        // 写入文件中
        dataEncoding.writeToFile(filePath, atomically: true)

        // 读取
        // 从文件中初始化Data对象
        let dataDecoding = NSMutableData(contentsOfFile: filePath)
        // 初始化解码对象
        let archiveDecoding = NSKeyedUnarchiver(forReadingWithData: dataDecoding!)
        // 根据键值还原对象
        let dogAencoding:Dog = archiveDecoding.decodeObjectForKey("dogA") as! Dog
        archiveDecoding.finishDecoding()
        print(dogAencoding.name)

    }
}
// 自定义对象,注意腰继承的对象和遵守的协议
class Dog:NSObject,NSCoding {
    var name:String
    // 自定义的构造方法
    @objc init(name:String)
    {
        self.name = name
    }
    // 协议的写入数据的方法
    @objc func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.name, forKey: "name")
    }
    // 协议的读取数据的方法
    @objc required init?(coder aDecoder: NSCoder) {
        self.name = aDecoder.decodeObjectForKey("name") as! String
//        return nil
    }
}