Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read from a plist with Swift 3 iOS app

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

I have a basic iOS application with Swift3 elements in it.
I've created a plist file with some entries I want to read and display in my application. (No write access is necessary)

How can you read a value for a given key for a bundled plist file, in 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.

like image 285
James T Snell Avatar asked Oct 07 '16 06:10

James T Snell


2 Answers

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)        } } 
like image 129
Nirav D Avatar answered Oct 06 '22 13:10

Nirav D


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

like image 32
Jack Avatar answered Oct 06 '22 14:10

Jack