我在玩苹果的新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*类仍然有效,可以使用吗?
如果我想将.plist转换为Swift字典,这是我所做的:
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
// use swift dictionary as normal
}
}
为Swift 2.0编辑:
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
// use swift dictionary as normal
}
为Swift 3.0编辑:
if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
// use swift dictionary as normal
}
以下是我找到的解决方案:
let levelBlocks = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("LevelBlocks", ofType: "plist"))
let test: AnyObject = levelBlocks.objectForKey("Level1")
println(test) // Prints the value of test
我将测试类型设置为AnyObject,以关闭关于可能发生的意外推断的警告。
而且,它必须在类方法中完成。
访问并保存已知类型的特定值:
let value = levelBlocks.objectForKey("Level1").objectForKey("amount") as Int
println(toString(value)) // Converts value to String and prints it
斯威夫特5
如果你想获取某个键的特定值,那么我们可以使用下面的扩展,它使用Bundle上的infoDictionary属性。
可以使用Bundle.main.infoDictionary获取所有信息。在表单字典中plist值,因此我们可以直接使用Bundle上的object(forInfoDictionaryKey: key)方法查询
extension Bundle {
static func infoPlistValue(forKey key: String) -> Any? {
guard let value = Bundle.main.object(forInfoDictionaryKey: key) else {
return nil
}
return value
}
}
使用
guard let apiURL = Bundle.infoPlistValue(forKey: "API_URL_KEY") as? String else { return }
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").
我已经创建了一个简单的字典初始化器替换NSDictionary(contentsOfFile: path)。只要去掉NS。
extension Dictionary where Key == String, Value == Any {
public init?(contentsOfFile path: String) {
let url = URL(fileURLWithPath: path)
self.init(contentsOfURL: url)
}
public init?(contentsOfURL url: URL) {
guard let data = try? Data(contentsOf: url),
let dictionary = (try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any]) ?? nil
else { return nil }
self = dictionary
}
}
你可以这样使用它:
let filePath = Bundle.main.path(forResource: "Preferences", ofType: "plist")!
let preferences = Dictionary(contentsOfFile: filePath)!
UserDefaults.standard.register(defaults: preferences)