1 Reply
      Latest reply on Aug 23, 2017 1:39 AM by eskimo
      sleipn1r Level 1 Level 1 (0 points)

        Hi Developer,

         

        i want to access my Plist from URLRequest

         

        my Dictionary contains only [String:String]  Key/Value and 1 or more subKeys with array of Dic [string:string].

         

        it is not possible to create this Object directly from url or string result,

        workaround (save local as tmp.plist and readDictionary from this file)

        but the subkeys ( array of dic) are also of Tyle [String:ANY]

         

        the object from Data or String (urlresult block) is __NFCDictionary,so cast it and create new NSDictionary,init(dic),

        to Access the values now the values are not of Type ANY.

        is it possible to create the object of type Dictionary contains the result of plist and not [String:Any]

        to Access the Key/Values without create and init the new Dictionary ?

         

        thanks

        • Re: read NSDictionary from URLRequest
          eskimo Apple Staff Apple Staff (13,325 points)

          There are many ways to do type-safe decoding of property lists.  The nicest, at least in my opinion, is the PropertyListDecoder introduced in Swift 4.  For example, if you have a test.plist in your project whose contents looks like this:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
          <plist version="1.0">
          <dict>
              <key>key1</key>
              <string>value1</string>
              <key>key2</key>
              <string>value2</string>
          </dict>
          </plist>

          you can decode it like this:

          struct Test : Decodable {
              var key1: String
              var key2: String
          }
          
          func decoderTest() {
              let url = Bundle.main.url(forResource: "test", withExtension: "plist")!
              let data = try! Data(contentsOf: url)
              let decoder = PropertyListDecoder()
              let t = try! decoder.decode(Test.self, from: data)
              print(t)
          }

          Note that this ignores the possibility of error, which is a reasonable thing to do if the properly list is embedded in your app but is not acceptable if the property list comes from anywhere else.


          If you actively want to a [String:String], you can do this using PropertyListSerialization (Swift 3 or later).  For example:

          func serialisationTest() {
              let url = Bundle.main.url(forResource: "test", withExtension: "plist")!
              let data = try! Data(contentsOf: url)
              let d = try! PropertyListSerialization.propertyList(from: data, format: nil) as! [String:String]
              print(d)
          }

          Again, this is ignoring the possibility of error.  If the data is coming off the network, you’d want to use:

          • try (not try!), to catch property list format errors

          • as? (not as!), to catch the property list being of the wrong type

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"