如何使用 Swift 3 iOS 应用程序从 plist 中读取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39910461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:31:09  来源:igfitidea点击:

How to read from a plist with Swift 3 iOS app

iosswiftxcodeplistswift3

提问by James T Snell

-Disclaimer-
I'm extremely new to iOS and Swift development, but I'm not particularly new to programming.

-免责声明 -
我对 iOS 和 Swift 开发非常陌生,但我对编程并不是特别陌生。

I have a basic iOSapplication with Swift3elements in it.
I've created a plistfile with some entries I want to read and display in my application. (No write access is necessary)

我有一个iOS包含Swift3元素的基本应用程序。
我创建了一个plist文件,其中包含一些我想在我的应用程序中读取和显示的条目。(不需要写访问权限)

How can you read a value for a given key for a bundled plistfile, in Swift3?

如何plist在 Swift3 中读取捆绑文件的给定键的值?

This seems like a really simple question to me, but a bunch of searching is making me question my whole conceptual approach.

这对我来说似乎是一个非常简单的问题,但是一堆搜索让我质疑我的整个概念方法。

Helpful tips would be appreciated.

有用的提示将不胜感激。

回答by Nirav D

Same way you have done in Swift 2.3 or lower just syntax is changed.

与您在 Swift 2.3 或更低版本中所做的相同,只是更改了语法。

if let path = Bundle.main.path(forResource: "fileName", ofType: "plist") {

    //If your plist contain root as Array
    if let array = NSArray(contentsOfFile: path) as? [[String: Any]] {

    }

    ////If your plist contain root as Dictionary
    if let dic = NSDictionary(contentsOfFile: path) as? [String: Any] {

    }
}

Note:In Swift it is better to use Swift's generic type Array and Dictionary instead of NSArrayand NSDictionary.

注意:在 Swift 中最好使用 Swift 的泛型类型 Array 和 Dictionary 而不是NSArrayand NSDictionary

Edit:Instead of NSArray(contentsOfFile: path)and NSDictionary(contentsOfFile:)we can also use PropertyListSerialization.propertyList(from:)to read data from plistfile.

编辑:而不是NSArray(contentsOfFile: path)NSDictionary(contentsOfFile:)我们也可以利用PropertyListSerialization.propertyList(from:)从读取数据plist文件。

if let fileUrl = Bundle.main.url(forResource: "fileName", withExtension: "plist"),
   let data = try? Data(contentsOf: fileUrl) {
       if let result = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [[String: Any]] { // [String: Any] which ever it is 
            print(result)
       }
}

回答by Hyman

As Swift 4 introduces Codable

随着 Swift 4 引入Codable

Step 1: Load the Plist File from bundle.

步骤 1:从包中加载 Plist 文件。

Step 2: Use PropertyListDecoder for the decoding of property list values into semantic Decodabletypes.

步骤 2:使用 PropertyListDecoder 将属性列表值解码为语义Decodable类型。

Step 3: Create Codable Struct

第 3 步:创建可编码结构

Complete code -

完整代码——

 func setData() {
        // location of plist file
        if let settingsURL = Bundle.main.path(forResource: "JsonPlist", ofType: "plist") {

            do {
                var settings: MySettings?
                let data = try Data(contentsOf: URL(fileURLWithPath: settingsURL))
                    let decoder = PropertyListDecoder()
                settings = try decoder.decode(MySettings.self, from: data)
                    print("toolString is \(settings?.toolString ?? "")")
                print("DeviceDictionary is \(settings?.deviceDictionary?.phone ?? "")")
                print("RootPartArray is \(settings?.RootPartArray ?? [""])")

            } catch {
                print(error)
            }
        }
    }
}
struct MySettings: Codable {
    var toolString: String?
    var deviceDictionary: DeviceDictionary?
    var RootPartArray: [String]?

    private enum CodingKeys: String, CodingKey {
        case toolString = "ToolString"
        case deviceDictionary = "DeviceDictionary"
        case RootPartArray
    }

    struct DeviceDictionary: Codable {
        var phone: String?
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            phone = try values.decodeIfPresent(String.self, forKey: .phone)
        }
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        toolString = try values.decodeIfPresent(String.self, forKey: .toolString)
        deviceDictionary = try values.decodeIfPresent(DeviceDictionary.self, forKey: .deviceDictionary)
        RootPartArray = try values.decodeIfPresent([String].self, forKey: .RootPartArray)

    }
}

Sample Plist file -> https://gist.github.com/janeshsutharios/4b0fb0e3edeff961d3e1f2829eb518db

示例 Plist 文件 -> https://gist.github.com/janeshsutharios/4b0fb0e3edeff961d3e1f2829eb518db

回答by Eugene Martinson

Here is example how to get BundleID from Info plist:

以下是如何从 Info plist 获取 BundleID 的示例:

var appBundleID = "Unknown Bundle ID"    
if let bundleDict = Bundle.main.infoDictionary, 
   let bundleID = bundleDict[kCFBundleIdentifierKey as String] as? String {
       appBundleID = bundleID
   }

The same way you may easily access any key. This approach is good for many-target projects.

以同样的方式您可以轻松访问任何键。这种方法适用于多目标项目。

回答by Jerome

Here is a Swift 3implementation, based on Nirav D's answer:

这是一个Swift 3实现,基于Nirav D 的回答

    /// Read Plist File.
    ///
    /// - Parameter fileURL: file URL.
    /// - Returns: return plist content.
    func ReadPlist(_ fileURL: URL) -> [String: Any]? {
        guard fileURL.pathExtension == FileExtension.plist, let data = try? Data(contentsOf: fileURL) else {
            return nil
        }
        guard let result = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any] else {
            return nil
        }
        print(result)
        return result
    }

回答by FARAZ

For Swift 3.0, Following code directly targeting to key. Where as dictobject will give everything which will be there in your plist file.

对于 Swift 3.0,以下代码直接定位到键。其中dict对象将提供您的 plist 文件中的所有内容。

if let path = Bundle.main.path(forResource: "YourPlistFile", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
            let value = dict["KeyInYourPlistFile"] as! String
    }

回答by Amul4608

In AppDelegate File

在 AppDelegate 文件中

var bundlePath:String!
    var documentPath:String!
    var plistDocumentPath:URL!
    let fileManager = FileManager()


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        bundlePath = Bundle.main.path(forResource: "Team", ofType: "plist")

        documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first

        plistDocumentPath = URL.init(string: documentPath)?.appendingPathComponent("Team.plist")
        print(plistDocumentPath.path)

        if !fileManager.fileExists(atPath: plistDocumentPath.path){

            do {
                try fileManager.copyItem(atPath: bundlePath, toPath: plistDocumentPath.path)
            } catch  {
                print("error Occured \(error.localizedDescription)")
            }

        }


        return true
    }

In ViewController

在视图控制器中

 @IBOutlet weak var TeamTable: UITableView!
    var appDelegate:AppDelegate!
    var arrayForContacts:[[String:Any]]! // array object


    override func viewDidLoad() {
        super.viewDidLoad()




        appDelegate = UIApplication.shared.delegate as! AppDelegate


    }
    override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)

        if appDelegate.fileManager.fileExists(atPath: appDelegate.plistDocumentPath.path){
            arrayForContacts = []
            if let contentOfPlist = NSArray.init(contentsOfFile: appDelegate.plistDocumentPath.path ){
                arrayForContacts = contentOfPlist as! [[String:Any]]
                TeamTable.reloadData()
            }

        }
    }

回答by Deepak Carpenter

You can also read value directly from your plist file by simply

您还可以通过简单地直接从 plist 文件中读取值

let value = Bundle.init(for: AppDelegate.self).infoDictionary?["your plist key name"] as? Any