我在玩苹果的新Swift编程语言,遇到了一些问题…

目前我试图读取一个plist文件,在Objective-C中,我会做以下工作来获取内容作为NSDictionary:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];

我如何得到一个plist作为一个字典在Swift?

我假设我可以得到路径到plist:

let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")

当这工作(如果它是正确的?):我如何获得内容作为一个字典?

还有一个更普遍的问题:

是否可以使用默认的NS*类?我想是的……还是我遗漏了什么?据我所知,默认框架NS*类仍然有效,可以使用吗?


当前回答

在SWIFT语言中,你可以这样读plist:

let path = NSBundle.mainBundle().pathForResource("PriceList", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)

读单个字典值:

let test: AnyObject = dict.objectForKey("index1")

如果你想在plist中获得完整的多维字典:

let value: AnyObject = dict.objectForKey("index2").objectForKey("date")

下面是plist:

<plist version="1.0">
<dict>
<key>index2</key>
<dict>
    <key>date</key>
    <string>20140610</string>
    <key>amount</key>
    <string>110</string>
</dict>
<key>index1</key>
<dict>
    <key>amount</key>
    <string>125</string>
    <key>date</key>
    <string>20140212</string>
</dict>
</dict>
</plist>

其他回答

你仍然可以在Swift中使用nsdictionary:

Swift 4

 var nsDictionary: NSDictionary?
 if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
    nsDictionary = NSDictionary(contentsOfFile: path)
 }

Swift 3+

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
   let myDict = NSDictionary(contentsOfFile: path){
    // Use your myDict here
}

以及旧版本的Swift

var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
    myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
    // Use your dict here
}

NSClasses仍然可用,完全可以在Swift中使用。我想他们可能很快就会把重点转移到swift上,但是目前swift api并没有核心NSClasses的所有功能。

步骤1:简单和最快的方法来解析plist在swift 3+

extension Bundle {

    func parsePlist(ofName name: String) -> [String: AnyObject]? {

        // check if plist data available
        guard let plistURL = Bundle.main.url(forResource: name, withExtension: "plist"),
            let data = try? Data(contentsOf: plistURL)
            else {
                return nil
        }

        // parse plist into [String: Anyobject]
        guard let plistDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: AnyObject] else {
            return nil
        }

        return plistDictionary
    }
}

第二步:使用方法:

Bundle().parsePlist(ofName: "Your-Plist-Name")

访问plist文件的简单结构(Swift 2.0)

struct Configuration {      
  static let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  static let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  static let someValue = dict["someKey"] as! String
}

用法:

print("someValue = \(Configuration.someValue)")

Swift 2.0:访问信息。Plist

我有一个名为CoachMarksDictionary的字典,在信息中具有布尔值。Plist。我想访问bool值并使其为真。

let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  if let CoachMarksDict = dict["CoachMarksDictionary"] {
       print("Info.plist : \(CoachMarksDict)")

   var dashC = CoachMarksDict["DashBoardCompleted"] as! Bool
    print("DashBoardCompleted state :\(dashC) ")
  }

写给Plist:

自定义Plist:- Make from File-New-File-Resource-PropertyList。增加了三个字符串:DashBoard_New, DashBoard_Draft, DashBoard_Completed)

func writeToCoachMarksPlist(status:String?,keyName:String?)
 {
  let path1 = NSBundle.mainBundle().pathForResource("CoachMarks", ofType: "plist")
  let coachMarksDICT = NSMutableDictionary(contentsOfFile: path1!)! as NSMutableDictionary
  var coachMarksMine = coachMarksDICT.objectForKey(keyName!)

  coachMarksMine  = status
  coachMarksDICT.setValue(status, forKey: keyName!)
  coachMarksDICT.writeToFile(path1!, atomically: true)
 }

该方法可以调用为

self.writeToCoachMarksPlist(" true - means user has checked the marks",keyName: "the key in the CoachMarks dictionary").

下面是一个基于@connor的回答的简短版本

guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
    let myDict = NSDictionary(contentsOfFile: path) else {
    return nil
}

let value = dict.value(forKey: "CLIENT_ID") as! String?