read NSDictionary from URLRequest

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

Replies

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"