How to read from a plist with Swift 3 iOS app

前端 未结 7 1849
無奈伤痛
無奈伤痛 2020-12-24 06:49

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

I have a basic iOS applicati

相关标签:
7条回答
  • 2020-12-24 06:58

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

    let value = Bundle.init(for: AppDelegate.self).infoDictionary?["your plist key name"] as? Any
    
    0 讨论(0)
  • 2020-12-24 07:05

    As Swift 4 introduces Codable

    Step 1: Load the Plist File from bundle.

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

    Step 3: Create Codable Struct

    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

    0 讨论(0)
  • 2020-12-24 07:06

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

    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 NSArray and NSDictionary.

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

    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)
           }
    }
    
    0 讨论(0)
  • 2020-12-24 07:06

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

    if let path = Bundle.main.path(forResource: "YourPlistFile", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
                let value = dict["KeyInYourPlistFile"] as! String
        }
    
    0 讨论(0)
  • 2020-12-24 07:09

    In AppDelegate File

    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()
                }
    
            }
        }
    
    0 讨论(0)
  • Here is example how to get BundleID from Info plist:

    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.

    0 讨论(0)
提交回复
热议问题