MB Stephenson
MB Stephenson

Reputation: 169

Use URL to Load Plist File into Array

I created an app that includes an Employee Directory in a tableview. The app is working great using a plist file in my project to create an array of dictionaries, but the file changes often as employees come and go, so I really need to make it external to the Xcode project. I'm trying to do it using URL and NSURL, but having a problem getting this to work and need a fresh set of eyes. What is the best way to accomplish assuming the file is located at www.abc.com/directory.plist?
I'm sorry, I'm pretty much a programming beginner, but am learning as fast as I can!

Here's my functioning code:

class TableViewController: UITableViewController {

var filePath: String?
var employees: [[String: String]] = []

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.delegate = self
    self.tableView.dataSource = self

    filePath = Bundle.main.path(forResource: "directory", ofType: "plist")
    employees = NSArray(contentsOfFile: filePath!) as! [[String: String]]

    for item in employees {

        print(item["Name"] as Any)
        print(item.count)
        print(employees.count)
    }
}

EDIT -
I replaced NSArray with PropertyListSerialization in my code. Still working on adding remote file load with URLSession.

        if let filePath = Bundle.main.url(forResource: "directory", withExtension: "plist") {
        do {
            let data = try Data(contentsOf:filePath)
            employees = try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as! [[String : String]]

        } catch {
            print("Error loading file.")
        }
    }

Upvotes: 3

Views: 1376

Answers (3)

JimGilmore
JimGilmore

Reputation: 21

URLSession.shared.dataTask(with: filePath!) { (data, response, error) and PropertyListSerialization.propertyList(from: data, options: [] is definitely the way to go. Great job figuring it out and posting your answer here for the rest of the community.

Upvotes: 1

MB Stephenson
MB Stephenson

Reputation: 169

I got it working. Thank you for pointing me in the right direction with URLSession. I read Apple's documentation and then pieced together with Xcode autocomplete and several examples, some from vadian. I hope this helps someone else.

    override func viewDidLoad() {
    super.viewDidLoad()

    let filePath = URL(string: "https://www.example.com/directory.plist")
    URLSession.shared.dataTask(with: filePath!) { (data, response, error) in
        if error != nil {
            print("Error loading URL.")
        }
    }
    do {
            let data = try Data(contentsOf:filePath!)
            employees = try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as! [[String : String]]

            for item in employees {
                print(item["Name"] as Any)
                print(item.count)
                print(employees.count)
            }
    } catch {
           print("Error loading employee data.")
      }
  }

Upvotes: 3

Duncan C
Duncan C

Reputation: 131426

As others have said, you need to use NSURLSession (URLSession in Swift 3)

That is the modern way to do async downloading from a remote server.

I wrote a little demo project called Async_demo that you can download from Github that includes a class DownloadManager. You could drop that class into your project to download your plist data as a Data object. You'd then save that data to the app's documents or caches directory.

Upvotes: 1

Related Questions