plist读取 swift

2018-07-26 22:10:08 u011865919 阅读数 1059

在MacOS项目中使用Swift管理plist,实现读写plist文件。

1. Jobs.swift
使用Jobs类管理Jobs.plist

//  Jobs.swift
//  Created by Cyril on 18/7/11.
//  Copyright © 2018年 GJ. All rights reserved.
import Foundation
class Jobs: NSObject {
    var RestoreSequence_1: Dictionary<String , AnyObject?> = [:]
    var RestoreSequence_2: Dictionary<String , AnyObject?> = [:]
    var RestoreSequence_3: Dictionary<String , AnyObject?> = [:]
    let dModel = DataModel()
    //构造方法
    override init(){
        super.init()
        print("[Jobs] 初始化...")
        onCreateData("Jobs.plist")
        let d = dModel.loadData("Jobs", dFilePath: "Jobs.plist")
        let skey:String = "RestoreStage"
        print("查找\(skey)结果:\(dModel.searchValueByKey(d, skey: skey))")
    }
    func onCreateData(fileName: String){
        print("[Jobs]: 开始创建plist文件")
        //Document path   本地数据数据路径   .plist格式
        let fileManager = NSFileManager.defaultManager()
        let localDataPath:String = dModel.dataFilePath(fileName)
        print("[Jobs]: " + localDataPath)
        var isLocalDataExisted = fileManager.fileExistsAtPath(localDataPath)
        print("isLocalDataExisted->\(isLocalDataExisted)")

        //判断.plist文件是否存在
        if isLocalDataExisted == false//文件不存在
        {
            fileManager.createFileAtPath(localDataPath, contents: nil, attributes: nil)//创建.plist文件
        }
        isLocalDataExisted = fileManager.fileExistsAtPath(localDataPath)
        print("isLocalDataExisted->\(isLocalDataExisted)")

        //设置root
        let root = NSMutableDictionary()
        //设置dictionay
        root.setValue(
            [
                "RestoreSequence_1":[
                    "RestoreStage" : "P1",
                    "Input_Type" : "Uart_Diags",
                    "TempValues" : [
                        "MLBSN" : "#ProgramWriteToIt#",
                        "FGSN" : "#ProgramWriteToIt#",
                        "Mod#" : "#ProgramWriteToIt#",
                        "Regn" : "#ProgramWriteToIt#",
                    ],
                    "Command_Device" : [
                        "TTPowerSupply" : "#TT治具上电命令#",
                        "MLBSN" : "syscfg print MLB#",
                        "Write_FGSN" : "sn #FGSN#",
                        "Print_FGSN" : "sn",
                        "Write_Mod" : "syscfg add Mod# #Mod##",
                        "Print_Mod" : "syscfg print Mod#",
                        "Write_Regn" : "syscfg add Regn #Regn#",
                        "Print_Regn" : "syscfg print Regn",
                        "LogCollection" : "#LogCollection#",
                        "Restart" : "#TT治具重新上电命令#"
                    ],
                    "Command_Host" : [
                        "暂时为空" : "暂时为空"
                    ]
                ],
                "RestoreSequence_2":[
                    "RestoreStage" : "P2",
                    "Input_Type" : "Uart_iBoot",
                    "TempValues" : [
                        "MLBSN" : "#ProgramWriteToIt#",
                        "FGSN" : "#ProgramWriteToIt#",
                        "#暂时为空#" : "#暂时为空#",
                    ],
                    "Command_Device" : "#暂时为空#",
                    "Command_Host" : [
                        "暂时为空" : "暂时为空"
                    ]
                ],
                "RestoreSequence_FG":[
                    "RestoreStage" : "FG",
                    "Input_Type" : "Uart_OS",
                    "TempValues" : [
                        "FGSN" : "#ProgramWriteToIt#",
                        "#暂时为空#" : "#暂时为空#",
                    ],
                    "Command_Device" : "#暂时为空#",
                    "Command_Host" : [
                        "暂时为空" : "暂时为空"
                    ]
                ],

            ], forKey: "Jobs")
        //将root写入.plist文件
        root.writeToFile(localDataPath, atomically: true)
        isLocalDataExisted = fileManager.fileExistsAtPath(localDataPath)
        if isLocalDataExisted == true{
            print("[Jobs]: Jobs.plist文件创建完成")
        }else{
            print("[Jobs]: Jobs.plist文件创建失败")
        }
        /*  try! fileManager.removeItemAtPath(localDataPath)//删除本地数据文件 */
    }    
}

2. DataModel.swift

//  DataModel.swift
//  Created by Cyril on 18/7/11.
//  Copyright © 2018年 GJ. All rights reserved.

import Foundation
class DataModel: NSObject {
    var userList = [UserInfo]()
   // var keyArray: Dictionary = [Int: String] ()
    //获取沙盒文件夹路径
    func documentsDirectory()->String {
        /*  let paths = NSSearchPathForDirectoriesInDomains(
         NSSearchPathDirectory.DocumentationDirectory,NSSearchPathDomainMask.UserDomainMask,true)
         let documentsDirectory:String = paths.first! as String */
        let path = "./Cyril/Anole"
        return path
    }

    /**
     获取数据文件地址
     Eg:
     fileName:userList.plist
     */
    func dataFilePath (fileName: String)->String{
        print(documentsDirectory().stringByAppendingString("/" + fileName))
        return documentsDirectory().stringByAppendingString( "/\(fileName)")
    }

    /**
     读取数据
     Eg:
     key: userList
     dFilePath: userList.plist
     */
    func loadData(key: String, dFilePath: String)-> NSDictionary{
        //判断.plist文件是否存在
        let fileManager = NSFileManager.defaultManager()
        let isLocalDataExisted = fileManager.fileExistsAtPath(self.dataFilePath(dFilePath))
        print("isLocalDataExisted->\(isLocalDataExisted)")
        if isLocalDataExisted == false//文件不存在
        {
            fileManager.createFileAtPath(self.dataFilePath(dFilePath), contents: nil, attributes: nil)//创建.plist文件
        }
        let dicFromPList: NSDictionary? = NSDictionary(contentsOfFile: "/Users/coreos/Desktop/Cyril/Anole/Jobs_P1P2FG.plist")
        print("文件 " + dFilePath + " 读取完成")
        return dicFromPList!
    }

    /**
     * 通过key查找在字典中的value值
     */
    func searchValueByKey(dic: NSDictionary, skey: String)-> String{
        var printHead = "[searchValueByKey]: "
        if (dic.count == 0){
            return printHead + "输入的参数字典为空"
        }
        //plist 四层结构遍历(尚有bug未更正)
        for (key1, value1) in (dic as! NSMutableDictionary) {
      //      keyArray.updateValue(key as! String, forKey: 1)
            print("第1层->字典 key \(key1) -  字典 value () \(value1)")
            if(key1 as! String == skey){
                print("\(printHead)\(skey)查找成功, 为根字典")
                return "查找的\(skey)的值为\(value1)"
            }
            for (key2, value2) in (value1 as! NSMutableDictionary) {
                print("第2层->字典 key \(key2) -  字典 value \(value2)")
                if(key2 as! String == skey){
                    print("\(printHead)\(skey)查找成功, 在字典\(key1)下")
                    return "查找的\(skey)的值为\(value2)"
                }
                for (key3, value3) in (value2 as! NSMutableDictionary) {

                    print("第3层->字典 key \(key3) -  字典 value \(value3)")
                    if(key3 as! String == skey){
                        print("\(printHead)\(skey)查找成功, 在字典\(key2)下")
                        return "查找的\(skey)的值为\(value3)"
                        for (key4, value4) in (value3 as! NSMutableDictionary) {

                            print("第4层->字典 key \(key4) -  字典 value \(value4)")
                            if(key4 as! String == skey){
                                print("\(printHead)\(skey)查找成功, 在字典\(key3)下")
                                return "查找的\(skey)的值为\(value4)"
                            }
                        }
                    }
                }
            }
        }
        return "\(printHead)输入的参数字典为空"
    }

    /**
     *  值类型判断
     */
    func judgeValueType(dic: AnyObject) -> String{
        if let dict1 = dic as? NSMutableDictionary{
            return "NSMutableDictionary"
        }else if let dict1 = dic as? NSDictionary{
            return "NSDictionary"
        }else if let dict1 = dic as? NSArray{
            return "NSArray"
        }else if  let dict1 = dic as? NSValue{
            return "NSValue"
        }else{
            return "\(dic)" //其他可能是字串类型
        }
    }
}
2018-07-27 10:52:52 weixin_41735943 阅读数 2064

plist文件的读写这部分有个坑,在Xcode中创建的plist文件在代码运行时是只读的,你可以正确写入读出,但是无法持久化存储。如果想做持久化,必须用代码在沙箱目录中创建plist文件。因为Xcode创建的plist文件和程序代码同级,就如同你无法在运行时修改程序代码。

读取Xcode中手动创建的Plist文件

//生成文件的存储路径
let plistPath = Bundle.main.path(forResource: "demoPlist", ofType: "plist")

//读取属性列表文件,并转化为可变字典对象
let data:NSMutableDictionary = NSMutableDictionary.init(contentsOfFile: plistPath!)!
        
//将字典对象转化为字符串对象
let message = data.description

print(message)

在程序沙箱目录中创建可持久化存储的plist文件

//创建一个沙箱目录下的路径
let path = NSHomeDirectory() + "/Documents/testPlist.plist"
if let dic:NSMutableDictionary = NSMutableDictionary.init(contentsOfFile: path) {
    let message = dic.description
    print(message)
} else {
    let filemanger = FileManager.default
    //  对写入的数据结构应属于以下几种如下: NSString NSData NSDate NSNumber NSArray NSDictionary
    let dictionary:NSDictionary = ["name":"chen chao", "age":"18", "info":"Good Teacher"]
    do {
        // 序列化,将数据转换成 XML 格式的文件
        let data = try PropertyListSerialization.data(fromPropertyList: dictionary, format: .xml , options: .zero)
        //创建文件
        filemanger.createFile(atPath: path, contents: data, attributes: nil)
    } catch {
        print("error")
    }
}

 

2015-09-09 19:36:49 WorldViewController 阅读数 943

英文原文地址:http://www.swiftkiller.com/?p=559

或者:http://www.tuicool.com/articles/vY7vMjZ

项目代码:https://github.com/SandorNagy/ReadWritePlistTutorial

在许多iOS app中经常需要加载和保存数据。常见的有许多方法能完成这个功能:NSUserDefaults, CoreData,或者是用plist等等。今天这篇文章我将告诉大家怎么使用plist。

  下载资源

我们将用到一个GameData.plist。点击下载

打开它你会看到以下三个内容

  • BedroomFloor (代码中将要用到的带有ID的特定floor)
  • BedroomWall (代码中将要用到的带有ID的特定wall)
  • XInitializerItem (代码中将要用到的,不能被改变的)
创建工程
创建一个简单的工程,选择Single View Application.

然后起一个名字:ReadWritePlistTutorial,确保语言选择Swift

设置工程
好的,现在我们把刚才下载的GameData.plist拖到你的工程里。

确保选择了Copy items if needed并且目标是ReadWritePlistTutorial.

首先我们要为这个plist的关键字添加一些常量。添加下面代码到ViewController.swift里的import UIKit之后。
// MARK: == GameData.plist Keys ==
  let BedroomFloorKey = "BedroomFloor"
  let BedroomWallKey = "BedroomWall"
  // MARK: -
现在继续添加两个辅助变量在viewDidLoad方法前边。
// MARK: == Variables ==
  var bedroomFloorID: AnyObject = 101
  var bedroomWallID: AnyObject = 101
现在你的ViewController应该是这样

添加逻辑
我们想要能够在代码中使用plist文件元素,所以我们要把它转换成字典类型加载到我们的代码里。复制下面的代码在didReceiveMemoryWarning()方法之后。
func loadGameData() { 
  // getting path to GameData.plist
  let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
  let documentsDirectory = paths[0] as String
  let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
  let fileManager = NSFileManager.defaultManager()
  //check if file exists
  if(!fileManager.fileExistsAtPath(path)) {
    // If it doesn't, copy it from the default file in the Bundle
    if let bundlePath = NSBundle.mainBundle().pathForResource("GameData", ofType: "plist") {
      let resultDictionary = NSMutableDictionary(contentsOfFile: bundlePath)
      println("Bundle GameData.plist file is --> \(resultDictionary?.description)")
      fileManager.copyItemAtPath(bundlePath, toPath: path, error: nil)
      println("copy")
    } else {
    println("GameData.plist not found. Please, make sure it is part of the bundle.")
    }
  } else {
    println("GameData.plist already exits at path.")
    // use this to delete file from documents directory
    //fileManager.removeItemAtPath(path, error: nil)
  }
  let resultDictionary = NSMutableDictionary(contentsOfFile: path)
  println("Loaded GameData.plist file is --> \(resultDictionary?.description)")
  var myDict = NSDictionary(contentsOfFile: path)
  if let dict = myDict {
    //loading values
    bedroomFloorID = dict.objectForKey(BedroomFloorKey)!
    bedroomWallID = dict.objectForKey(BedroomWallKey)!
    //...
  } else {
    println("WARNING: Couldn't create dictionary from GameData.plist! Default values will be used!")
  }
}
    接下来添加下面的代码用来把值保存到plist文件中。
func saveGameData() {
  let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
  let documentsDirectory = paths.objectAtIndex(0) as NSString
  let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
  var dict: NSMutableDictionary = ["XInitializerItem": "DoNotEverChangeMe"]
  //saving values
  dict.setObject(bedroomFloorID, forKey: BedroomFloorKey)
  dict.setObject(bedroomWallID, forKey: BedroomWallKey)
  //...
  //writing to GameData.plist
  dict.writeToFile(path, atomically: false)
  let resultDictionary = NSMutableDictionary(contentsOfFile: path)
  println("Saved GameData.plist file is --> \(resultDictionary?.description)")
}
    就这样,我们运行一下来看编译的一切。
通常我们需要在app一开始运行时候就获取到plist中的数据,为此我们在viewDidLoad()中调用plist.

为了保存一些数据我们首先在Main.storyboard中创建一个button.


把它重命名,然后按住Ctrl键,点击按钮拖到ViewController.swift中以建立一个连接。


选择Action连接,命名为:SaveButtonTapped.

现在假设你想改变bedroomFloorID为999并且保存在plist中,添加以下代码到 saveButtonTapped IBAction.
//change bedroomFloorID variable value
  bedroomFloorID = 999
  //save the plist with the changes
  saveGameData()
    然后编译运行,点击Save按钮,看到在Log中的变化.


完成之后,如果你关闭app然后再次编译运行,BedroomFloorID 将会变为999
注:你可能想把Save按钮的位置在app屏幕上居中,然而那是另一个教程提示一下:



2015-11-17 23:28:05 Guanyajun1987 阅读数 1930

读取和存储数据是很多ios应用中常见的功能。有很多办法可以实现这个功能:NSUserDefaults、CoreData、使用plist等等。
今天要介绍的是如何使用plist来实现这个功能(使用swift语言)

下载资源

我们要使用一个GameData.plist文件,点击这里下载
打开它你将看到3个条目:
BedroomFloor(包括代码需要用到的具体floor的id)
BedroomWall(包括代码需要用到的具体wall的id)
XlnitializerItem(被代码使用 ,不要尝试去改变它)
这里写图片描述

创建你的项目

现在,让我们创建一个简单的项目。建立一个”Single View Application”
这里写图片描述

然后,将项目名设置为:ReadWritePlistTutorial并且选择Swift作为编程语言
这里写图片描述

设置你的项目
好,现在把GameData.plist文件拖进你的项目
这里写图片描述

要选择”Copy items if needed”并且目标地址选择”ReadWritePlistTutorial”
这里写图片描述

首先,我们要给plist Keys添加一些常量,添加在ViewController.swift文件中,在import UIKit之后
swift

// MARK: == GameData.plist  Keys ==
let BedroomFloorKey = "BrdroomFloor"
let BedroomWallKey = "BedroomWall"
// MARK: -

现在,我们要添加两个辅助变量,添加在viewDidLoad()方法前
swift

//MARK: == Variables ==
var bedroomFloorID: AnyObject = 101
var bedroomWallID: AnyObject = 101

现在ViewController.swift文件应该是这样:
这里写图片描述

添加逻辑

我们想在代码中使用plist的元素,所以我们要把它读到代码中转换为字典。拷贝这段代码到didReceiveMemoryWarning()方法下面
swift

func loadGameData() {
    // 获取GameData.plist的地址
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths[0]
    let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
    let fileManager = NSFileManager.defaultManager()
    //确认文件是否存在
    if(!fileManager.fileExistsAtPath(path)) {
    // 如果不存在,就从bundle中拷贝一份默认文件
        if let bundlePath = NSBundle.mainBundle().pathForResource("GameData", ofType: "plist") {
           let resultDictionary = NSMutableDictionary(contentsOfFile: bundlePath)
           print("Bundle GameData.plist file is --> \(resultDictionary?.description)")
           do{
               try fileManager.copyItemAtPath(bundlePath, toPath: path)
           } catch{
                    print("copy")}
        } else {
            print("GameData.plist not found. Please, make sure it is part of the bundle.")
            }
    } else {
        print("GameData.plist already exits at path.")
        // 使用这条命令删除目录中的文件
        //fileManager.removeItemAtPath(path, error: nil)
    }
    let resultDictionary = NSMutableDictionary(contentsOfFile: path)
    print("Loaded GameData.plist file is --> \(resultDictionary?.description)")
    let myDict = NSDictionary(contentsOfFile: path)
    if let dict = myDict {
        //读取数值
        bedroomFloorID = dict.objectForKey(BedroomFloorKey)!
        bedroomWallID = dict.objectForKey(BedroomWallKey)!
        //...
    } else {
        print("WARNING: Couldn't create dictionary from GameData.plist! Default values will be used!")
    }
}

然后添加这段代码来存储对plist的改动
swift

func saveGameData() {
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
        let documentsDirectory = paths.objectAtIndex(0) as! NSString
        let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
        let dict: NSMutableDictionary = ["XInitializerItem": "DoNotEverChangeMe"]
        //存储数值
        dict.setObject(bedroomFloorID, forKey: BedroomFloorKey)
        dict.setObject(bedroomWallID, forKey: BedroomWallKey)
        //...
        //写入GameData.plist
        dict.writeToFile(path, atomically: false)
        let resultDictionary = NSMutableDictionary(contentsOfFile: path)
        print("Saved GameData.plist file is --> \(resultDictionary?.description)")
    }

通常我们需要在程序启动时读取plist的数据,所以把读取plist的方法添加到viewDidLoad()中
这里写图片描述

添加按钮

要存储数据让我们现在故事版中创建一个按钮
这里写图片描述

重命名为“Save”并且按住Ctrl并拖动它到ViewController.swift来创建一个连接
这里写图片描述

选择Action连接并且输入名字:SaveButtonTapped
这里写图片描述

现在我们要把bedroomFloorID变为999并且保存到plist。
添加下面的代码到刚刚创建的IBAction里面:
swift

//改变bedroomFloorID的值
bedroomFloorID = 999
//保存修改到plist
saveGameData()

编译并运行

点击“Save”按钮,你将看到log中打印的变化记录
这里写图片描述

我们完成了。如果你关闭模拟器,并再次编译运行,会看到BedroomFloorID还是999.
另外,你可以把Save按钮设置在屏幕的正中间
提示:
这里写图片描述

2018-08-23 19:54:38 kuangdacaikuang 阅读数 1431
import UIKit

//向指定的plist中写入数据--fileName:  text.plist
class ZQPredictProductIdSaveManager: NSObject {

    //写入
    class func saveData(key: String, value: Any, fileName: String) -> () {
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
        let documentsDirectory = paths.object(at: 0) as! NSString
        let path = documentsDirectory.appendingPathComponent(fileName)
        let dict: NSMutableDictionary = NSMutableDictionary()
        dict.setValue(value, forKey: key)
        dict.write(toFile: path, atomically: false)
    }

    //读取
    class func researchData(key: String, fileName: String) -> Any {
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
        let documentsDirectory = paths[0] as! NSString
        let path = documentsDirectory.appendingPathComponent(fileName)
        let fileManager = FileManager.default
        if(!fileManager.fileExists(atPath: path)) {
            if let bundlePath = Bundle.main.path(forResource: fileName, ofType: nil) {
                try! fileManager.copyItem(atPath: bundlePath, toPath: path)
            } else {
                print(fileName + " not found. Please, make sure it is part of the bundle.")
            }
        } else {
            print(fileName + " already exits at path.")
        }
        let myDict = NSDictionary(contentsOfFile: path)
        if let dict = myDict {
            return dict.object(forKey: key) ?? ""
        } else {
            print("WARNING: Couldn't create dictionary from " + fileName + "! Default values will be used!")
            return ""
        }
    }
}

plist 读取 swift

阅读数 10