• Part 10:iOS的数据持久化(1),文件,归档


    本章中主要学习数据持久化与各种持久化方式的实现方法

    沙箱目录 

    沙箱目录设计的原理就是只能允许自己的应用访问目录,而不允许其他的应用访问。

    1. Documents 目录 大量的数据,经常变化,最重要的是这个目录中数据,iCLoud 和 iTunes 备份。

    2. Library 目录

    使用偏好(系统设置)、缓存数据,不进行 iCLoud 和 iTunes 备份。

    3. tmp 目录

    临时数据,不进行 iCLoud 和 iTunes 备份。经常会被清除的。

    沙箱目录与资源目录的区别: 资源目录中的内容是只 读的,沙箱目录是放置那些可以读写的数据的。

    持久化方式 

    1.属性列表文件,集合对象可以读写到属性列表文件中。

    2.对象归档,一个对象状态和被保持到归档文件中。

    3.SQLite 数据库,SQLite 是个开源嵌入式关系型数据库。 

    4.CoreData,本质上也是通过 SQLite 存储的,它是一种对象关系映射技术(ORM)。

    以下为本章中实现的Demo代码

    展示层:View/MarterViewController.swift、DetailViewController.swift、AddViewController.swift

    MarterViewController.swift

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    import UIKit

    //表视频主页面

    class MarterViewController: UITableViewController {

        var objects = NSMutableArray()

         

        let Controller:NoteController = NoteController()

         

        override func viewDidLoad() {

            super.viewDidLoad()

            //代码实现左侧按钮

            self.navigationItem.leftBarButtonItem = self.editButtonItem

             

            self.objects = self.Controller.findAll()

             

            //(接收通知)监听通知事件RegisterCompletionNotification,交给registerCompletion函数处理

            NotificationCenter.default.addObserver(self, selector: #selector(CreateNoteList(notification:)), name: NSNotification.Name.init(rawValue: "CreateNoteList"), object: nil)// . object: nil 可以发送通知的视图接收过来

             

        }

        override func didReceiveMemoryWarning() {

            super.didReceiveMemoryWarning()

            // Dispose of any resources that can be recreated.

        }

         

        //TableViewDataSource 协议方法实现

        //返回表视图节的个数

        override func numberOfSections(in tableView: UITableView) -> Int {

            // #warning Incomplete implementation, return the number of sections

            return 1

        }

         

        //返回表视图每个节中的行数

        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            // #warning Incomplete implementation, return the number of rows

            return self.objects.count

        }

         

        //返回每一个 自定义cell 的内容

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            //请求可重用单元格,需要一个标识,CustomCellTableViewCell为自定义单元格类

            let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier"for: indexPath)

             

            let object = self.objects[indexPath.row] as! Note//查询数组中的Note出来

            cell.textLabel!.text = object.Content as String//取Note的Content的属性

            return cell

        }

         

        //点击Cell会触发视图控制器的Segue方法

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            //判断是跳转的哪个segue,showtow为segue在故事板中定义的identifier

            if segue.identifier == "toDetail" {

                //得到二级(Detail控制器)

                let datailVC = segue.destination as! DetailViewController

                //当前表视图被选择单元格

                let indexPath = self.tableView.indexPathForSelectedRow

                //当前单元格所对应的Note对象

                let object = self.objects[(indexPath?.row)!] as! Note

                //将信息传给二级的listData

                datailVC.listData = object.Content as String

                //设置二级表视图名称

                datailVC.title = "Detail"

            }

        }

         

        override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

            // 如果不希望指定项可编辑,则返回false

            return true

        }

         

        //进行操作,当前主要处理delete操作

        override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

            if editingStyle == .delete {

                let removeNote = self.objects[indexPath.row] as? Note

                self.objects = self.Controller.remove(model: removeNote!)

                tableView.deleteRows(at: [indexPath], with: .left)

            else if editingStyle == .insert {

                // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.

            }

        }

         

        //实现通知监听方法

        func CreateNoteList(notification : NSNotification) {

            let allData = notification.object as! NSMutableArray//取到投送过来对像

            self.objects = allData//拿到的数据给当前视图的变量

            self.tableView.reloadData()//重新加载当前表视图

             

        }

    }

    DetailViewController.swift

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    import UIKit

    //点击表视频图后进入的详细页面

    class DetailViewController: UIViewController {

         

        @IBOutlet weak var DetailLebel: UILabel!

         

        var listData:String!

        override func viewDidLoad() {

            super.viewDidLoad()

             

            self.DetailLebel.text = self.listData

             

        }

        override func didReceiveMemoryWarning() {

            super.didReceiveMemoryWarning()

            // Dispose of any resources that can be recreated.

        }   

    }

    AddViewController.swift

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    import UIKit

    //添加备忘录

    class AddViewController: UIViewController {

        @IBOutlet weak var textField: UITextField!

         

        let Controller:NoteController = NoteController()

         

         

        @IBAction func onDone(_ sender: UIBarButtonItem) {

            self.textField.resignFirstResponder()//username放弃第一响应者

            self.dismiss(animated: true, completion: nil)//关闭模态

        }

         

        @IBAction func onSave(_ sender: UIBarButtonItem) {

             

            //实例化一个新的Note

            let note = Note(date: NSDate(), content: self.textField.text! as NSString)//NSDate(),为当前日期

            //调用业务逻辑层的createNote方法,会返回添加后的所有数据

            let objs = Controller.createNote(model: note)

            //注册通知,传输数据 . object: objs 把返回的所有数据投送出去

            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "CreateNoteList"), object: objs, userInfo: nil)

             

            self.dismiss(animated: true, completion: nil)//关闭模态

            self.textField.resignFirstResponder()//username放弃第一响应者

        }

         

        override func viewDidLoad() {

            super.viewDidLoad()

            //注册点击事件

            self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))

        }

        override func didReceiveMemoryWarning() {

            super.didReceiveMemoryWarning()

            // Dispose of any resources that can be recreated.

        }

         

        //点击空白处关闭键盘方法

        func handleTap(sender: UITapGestureRecognizer) {

            if sender.state == .ended {

                self.textField.resignFirstResponder()//username放弃第一响应者

            }

            sender.cancelsTouchesInView = false

        }

    }

    业务逻辑层:Controller/NoteController.swift

    NoteController.swift,等等四种持久化方式都用一个业务逻辑类

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    import Foundation

    //业务逻辑层,Note为plist,NoteCoding为归档,,等等四种持久化方式都用一个业务逻辑类

    class NoteController {

        

        //查询所用数据方法

        func findAll() -> NSMutableArray {

            let dao:NoteModelSQlite = NoteModelSQlite.sharedFoo

            return dao.findAll()

        }

         

        //插入Note方法

        func createNote(model: Note) -> NSMutableArray {

            let dao:NoteModelSQlite = NoteModelSQlite.sharedFoo

            dao.create(model: model) //会有警告,因为create方法有返回值但在这里并没有使用

            return dao.findAll()

        }

         

        //删除Note方法

        func remove(model: Note) -> NSMutableArray {

            let dao:NoteModelSQlite = NoteModelSQlite.sharedFoo

            dao.remove(model: model)

            return dao.findAll()

        }

    }

    数据持久层:Model/Note.swift、NoteModel.swift、NoteCoding.swift、NoteModelCoding.swift、NoteModelSQlite.swift、DemoApp-10-Bridging-Header.h(OC的头文件)

    业务领域对像类:Note.swift,等等四种持久化方式都用一个业务领域对象类

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    import Foundation

    //业务领域对象类

    class Note {

         

        let Date: NSDate

        var Content: NSString

         

        init(date:NSDate,content:NSString) {

            self.Date date

            self.Content = content

        }

         

    }

    plist文件方式:NoteModel.swift

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    import Foundation

    //plist文件方式

    class NoteModel {

         

        let dateFormatter : DateFormatter = DateFormatter()

         

        private static let sharedInstance = NoteModel() //单例的实例保存这个属性中

        class var sharedFoo: NoteModel { //swift中的静态计算属性

             

            //初始化 拷贝文件到沙箱

            sharedInstance.plistCopyDocument()

             

            return sharedInstance

        }

         

         

        //修改Note方法

        public func modify(model: Note) -> Int {

             

            let path = self.getDocumentPath()

            let array = NSMutableArray(contentsOfFile: path)

             

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array! {

                let dict = item as! NSDictionary

                 

                let strDate = dict["date"as! String

                let date = dateFormatter.date(from: strDate)!

                 

                //比较日期主键是否相等

                if date == model.Date as Date {

                    //修改字典中的某个对应content key的值

                    dict.setValue(model.Content, forKey: "content")

                    //在次写入文件

                    array?.write(toFile: path, atomically: true)

                }

            }

             

            return 0

        }

         

         

        //插入Note方法

        public func create(model: Note) {

             

            let path = self.getDocumentPath()

            let array = NSMutableArray(contentsOfFile: path)

             

            //将日期转为字符串

            let strDate = dateFormatter.string(from: model.Date as Date)

            //组成一个字典元素

            let dict = NSDictionary(objects: [model.Content,strDate], forKeys: ["content" as NSCopying,"date" as NSCopying])

            //把字典元素添加到数组中

            array?.add(dict)

            //插入到文件

            array?.write(toFile: path, atomically: true)

        }

         

        //删除Note方法

        public func remove(model: Note) {

             

            let path = self.getDocumentPath()

            let array = NSMutableArray(contentsOfFile: path)

             

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array! {

                let dict = item as! NSDictionary

                 

                let strDate = dict["date"as! String

                let date = dateFormatter.date(from: strDate)!

                 

                //比较日期主键是否相等

                if date == model.Date as Date {

                    array?.remove(dict)//删除数组元素中的对应字典

                    //写入文件

                    array?.write(toFile: path, atomically: true)

                }

            }

             

        }

         

        //根据主键查询一条数据

        func findByid(model:Note) -> Note? {

            //实例时间对象于格式化

             

            self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

             

            let SXplist = self.getDocumentPath()

            let array = NSArray(contentsOfFile: SXplist)

             

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array! {

                let dict = item as! NSDictionary//取到数组中的每一个字典

                let strDate = dict["date"as! String//将字典中key的date取出

                let date = dateFormatter.date(from: strDate)!

                if date == model.Date as Date {

                    let content = dict["content"as! String//将字典中的content取出

                    let note = Note(datedate as NSDate, content: content as NSString)

                    return note

                }

            }

            return nil

        }

         

         

        //查询所有数据方法

        func findAll() -> NSMutableArray {

             

            //实例时间对象于格式化

            self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

             

            //得到已拷贝到沙箱目录的plist文件

            let SXplist = self.getDocumentPath()

            //将文件读到变量中,array中是数组套字典的格式

            let array = NSArray(contentsOfFile: SXplist)

            //字义可变数组对象

            let listData  = NSMutableArray()

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array! {

                let dict = item as! NSDictionary//取到数组中的每一个字典

                let strDate = dict["date"as! String//将字典中key的date取出

                let date = dateFormatter.date(from: strDate)!

                let content = dict["content"as! String//将字典中的content取出

                let note = Note(datedate as NSDate, content: content as NSString)//实例化note对象,返回一个note对象

                listData.add(note)//添加到可变数组中

            }

            return listData

        }

         

        //将plist文件拷贝到沙箱Document目录

        func plistCopyDocument() {

            //获得FileManager的单例

            let fileManager = FileManager.default

             

            //获得资源目录

            let defaultDBPath = Bundle.main.resourcePath as String!

            //在defaultDBPath字符串的基础上累加另一个字符串NotesList.plist,目录+文件路径

            let dbFile = defaultDBPath?.appending("/NotesList.plist")

             

            //目录+文件路径

            let writablepaht = self.getDocumentPath()

             

            //判断文件是否存在,如果存在则不重复拷贝

            let dbexits = fileManager.fileExists(atPath: writablepaht)

            if dbexits != true {

                do {//当代码提示后有throws时, 需要 try一下 有抛出异常的操作

                    //拷贝资源目录的文件 to 沙箱目录中

                    try fileManager.copyItem(atPath: dbFile!, toPath: writablepaht)

                }catch {

                    //使用断言方法,如果bool为false,会打印message字符串

                    //assert(bool, message)

                    print("出现异常")

                }

            }

             

            //print(writablepaht)

        }

         

        //获取系统沙箱Document目录方法

        func getDocumentPath() -> String {

            let documentDirectory: NSArray = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray

            let myDocPath = documentDirectory[0] as! NSString

            //在myDocPath字符串的基础上累加另一个字符串NotesList.plist,目录+文件路径

            let wtFile = myDocPath.appending("/NotesList.plist"as String

            return wtFile

        }

         

    }

    归档方式:NoteCoding.swift,NoteModelCoding.swift

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    177

    178

    179

    180

    181

    182

    183

    184

    185

    186

    187

    188

    189

    190

    191

    192

    193

    194

    195

    196

    197

    198

    199

    200

    201

    202

    203

    204

    205

    206

    207

    208

    209

    210

    211

    212

    213

    214

    215

    216

    217

    218

    219

    import Foundation

    //归档与反归档,被归档条件,1必须是NSObject对象,2必须实现NSCoding这个协议

    class NoteCoding: NSObject, NSCoding {

         

        let Date: NSDate

        var Content: NSString

         

        init(date:NSDate,content:NSString) {

            self.Date date

            self.Content = content

        }

         

        //NSCoding要求实现的 “解码” 在反归档时候调用的,必须要求实现的,“应该” 内部调用

        public required init?(coder aDecoder: NSCoder) {

            self.Date = aDecoder.decodeObject(forKey: "Date"as! NSDate

            self.Content = aDecoder.decodeObject(forKey: "Content"as! NSString

        }

         

        //NSCoding要求实现的 “编码” 在归档时候调用的,必须要求实现的,“应该” 内部调用

        public func encode(with aCoder: NSCoder) {

            aCoder.encode(self.Date, forKey: "Date")

            aCoder.encode(self.Content, forKey: "Content")

        }

         

    }

    =============================

    import Foundation

    //归档与反归档

    class NoteModelCoding: NSObject {

         

        //保存数据列表

        var listData: NSMutableArray!

        //归档与返归档用到的KEY

        let ARCH_KEY = "ackksy"

         

        let dateFormatter : DateFormatter = DateFormatter()

         

        private static let sharedInstance = NoteModelCoding() //单例的实例保存这个属性中

        class var sharedFoo: NoteModelCoding { //swift中的静态计算属性

             

            //初始化 创建归档文件

            sharedInstance.plistCopyDocument()

             

            return sharedInstance

        }

         

         

        //修改Note方法

        public func modify(model: NoteCoding) -> Int {

             

            let path = self.getDocumentPath()

            //获得所有数据

            let array = self.findAll()

             

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array {

                let note = item as! NoteCoding

                 

                //比较日期主键是否相等

                if note.Date == model.Date {

                    note.Content = model.Content//修改数据,待测试...

                     

                    //array进行归档

                    let data = NSMutableData()

                    let archiver = NSKeyedArchiver(forWritingWith: data)

                    archiver.encode(array, forKey: ARCH_KEY)

                    archiver.finishEncoding()

                    data.write(toFile: path, atomically: true)

                    break

                }

            }

             

            return 0

        }

         

         

        //插入Note方法

        public func create(model: NoteCoding) {

             

            let path = self.getDocumentPath()

            let array = self.findAll()

            array.add(model)

             

            //array进行归档

            let data = NSMutableData()

            let archiver = NSKeyedArchiver(forWritingWith: data)

            archiver.encode(array, forKey: ARCH_KEY)

            archiver.finishEncoding()

            data.write(toFile: path, atomically: true)

             

        }

         

        //删除Note方法

        public func remove(model: NoteCoding) {

             

            let path = self.getDocumentPath()

            //获得所有数据

            let array = self.findAll()

             

            //业务逻辑层的数据的数组中套Note。因此我们需要转换。

            for item in array {

                let note = item as! NoteCoding

                 

                //比较日期主键是否相等

                if note.Date == model.Date {

                    array.remove(note)//删除当前匹配出的Note

                     

                    //array进行归档

                    let data = NSMutableData()

                    let archiver = NSKeyedArchiver(forWritingWith: data)

                    archiver.encode(array, forKey: ARCH_KEY)

                    archiver.finishEncoding()

                    data.write(toFile: path, atomically: true)

                    break

                }

            }

             

        }

         

        //根据主键查询一条数据

        func findByid(model:NoteCoding) -> NoteCoding? {

            //得到已拷贝到沙箱目录的plist文件

            let SXplist = self.getDocumentPath()

            //将归档文件读取到Data中

            let data = NSData(contentsOfFile: SXplist)!

             

            if data.length > 0 {//判断文件是否读取成功

                //开始反归档

                //定义反归档对象,与data关联

                let unarchiver = NSKeyedUnarchiver(forReadingWith: data as Data)

                //解码ARCH_KEY的归档文件 并 转为可变数组赋值给listData

                self.listData = unarchiver.decodeObject(forKey: ARCH_KEY) as! NSMutableArray

                //结束反归档

                unarchiver.finishDecoding()

                 

                //业务逻辑层的数据的数组中套Note。因此我们需要转换。

                for item in self.listData {

                    let note = item as! NoteCoding

                    //比较日期主键是否相等

                    if note.Date == model.Date {

                        return note

                    }

                }

            }

            return nil

        }

         

         

        //查询所有数据方法

        func findAll() -> NSMutableArray {

             

            //得到已拷贝到沙箱目录的plist文件

            let SXplist = self.getDocumentPath()

            //将归档文件读取到Data中

            let data = NSData(contentsOfFile: SXplist)!

             

            if data.length > 0 {//判断文件是否读取成功

                //开始反归档

                //定义反归档对象,与data关联

                let unarchiver = NSKeyedUnarchiver(forReadingWith: data as Data)

                //解码ARCH_KEY的归档文件 并 转为可变数组赋值给listData

                self.listData = unarchiver.decodeObject(forKey: ARCH_KEY) as! NSMutableArray

                //结束反归档

                unarchiver.finishDecoding()

            }

            return self.listData

        }

         

        //将plist文件拷贝到沙箱Document目录

        func plistCopyDocument() {

            //获得FileManager的单例

            let fileManager = FileManager.default

            //目录+文件路径

            let writablepaht = self.getDocumentPath()

            //判断文件是否存在,如果存在则不重复拷贝

            let dbexits = fileManager.fileExists(atPath: writablepaht)

             

            if dbexits != true {

                //添加一些测试数据

                self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

                let date1: NSDate = self.dateFormatter.date(from: "2015-01-01 16:01:03")! as NSDate

                let note1: NoteCoding = NoteCoding(date:date1, content: "Welcome to MyNote.")

                 

                let date2: NSDate = self.dateFormatter.date(from: "2015-01-02 8:01:03")! as NSDate

                let note2: NoteCoding = NoteCoding(date:date2, content: "欢迎使用MyNote。")

                 

                //定义一个listData:NSMutableArray常量后,需要在实例化NSMutableArray()

                self.listData = NSMutableArray()

                self.listData.add(note1)

                self.listData.add(note2)

                 

                //进行归档

                let data = NSMutableData()//归档需要可变的Data实例

                let archiver = NSKeyedArchiver(forWritingWith: data)//定义归档对象,与data关联

                archiver.encode(self.listData, forKey: self.ARCH_KEY)//编码listdata数组到ARCH_KEY中

                archiver.finishEncoding()//完成编码

                data.write(toFile: writablepaht, atomically: true)//写入归档文件

            }

             

            //print(writablepaht)

        }

         

        //获取系统沙箱Document目录方法

        func getDocumentPath() -> String {

            let documentDirectory: NSArray = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray

            let myDocPath = documentDirectory[0] as! NSString

            //在myDocPath字符串的基础上累加另一个字符串NotesList.plist,目录+文件路径

            let wtFile = myDocPath.appending("/NotesList.fo"as String

            return wtFile

        }

         

    }


    此处接 Part 10:iOS的数据持久化(2),Sqlite,CoreData

  • 相关阅读:
    squid反向代理
    9.30消息队列实现进程之间通信方式代码,现象
    Revive开发商加入VR开源标准OpenXR
    DevOps 团队如何防御 API 攻击
    Linux软件包管理— rpm软件包查询
    C#【疑难杂症篇】CS0012:必须添加对程序集“netstandard, Version=2.0.0.0, Culture=neutral...”的引用
    elasticsearch-5.6.15集群部署,如何部署x-pack并添加安全认证
    【深度学习 AIGC】stablediffusion-infinity 在无界限画布中输出绘画 Outpainting
    学习ASP.NET Core Blazor编程系列七——新增图书
    客服支持Chatbot提供即时回答,改善用户体验
  • 原文地址:https://blog.csdn.net/zjwlgr/article/details/126119225