Get an external plist file. Show and modify some lines

Hello, at first time I apologize for my bad English and for my low level with swift code. I am a starter.

I have a doubt. I have searched in internet and I couldn't find any solution.
I want:

  1. Get a plist file from a specific directory, for example: "/Users/wargadex/Library/Cookies/HTST.plist"

  2. Show some lines of this file, for example, on text field in windows.

  3. Modify some lines and save file in the same place.

It's possible?

Thanks so much and best regards

You don’t need to apologize for attempting to use someone else’s language. It is something to be proud of.

Do you mean “in Windows”, the operating system? Or do you mean “in a window”, the user interface element (on, for example, macOS)?

1 Like

The path you mentioned, /Users/wargadex/Library/Cookies/HTST.plist, looks like a macOS path, suggesting that you’re targeting macOS. If so, you may run into privilege problems here. On modern versions of macOS, the ~/Library/Cookies/ directory is a data vault, which is inaccessible even to programs running as root.

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.5
BuildVersion:	18F132
$
$ ls -lh ~/Library/Cookies/
ls: : Operation not permitted
$
$ sudo ls -lh ~/Library/Cookies/
Password: ********
ls: : Operation not permitted

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Yes, I want do it in macOS.

Anyway, the swift code is a language indistinctly os the operative OS, no?
I guess only a few details change according to the OS

I did not know that. It’s interesting to know.
However, this is not important now. I'm just looking for a practical example.

Imagine that the file is on the desktop

Maybe this example will help you.

import Foundation

let url = URL(fileURLWithPath: "~/Desktop/foo.plist")

let data = try Data(contentsOf: url)

let encoder = PropertyListEncoder()

let decoder = PropertyListDecoder()

var dict = try decoder.decode([String:String].self, from: data)

dict["textField"] = "a"

let newData = try encoder.encode(dict)

try newData.write(to: url)

Sorry but I don't know as get it work.

Quick and dirty fix, please read Error handling

import Foundation

let url = URL(fileURLWithPath: "~/Desktop/foo.plist")

let data = try! Data(contentsOf: url)

let encoder = PropertyListEncoder()

let decoder = PropertyListDecoder()

var dict = try! decoder.decode([String:String].self, from: data)

dict["textField"] = "a"

let newData = try! encoder.encode(dict)

try! newData.write(to: url)

After reading the manual take a look at this code.

func plist() {
  let url = URL(fileURLWithPath: "~/Desktop/foo.plist")

  guard let data = try? Data(contentsOf: url) else { return }

  let encoder = PropertyListEncoder()

  let decoder = PropertyListDecoder()

  guard var dict = try? decoder.decode([String:String].self, from: data) else { return }

  dict["textField"] = "a"

  guard let newData = try? encoder.encode(dict) else { return }

  try? newData.write(to: url)
}

func read(url: URL)throws -> [String:String] {
  let data = try Data(contentsOf: url)
  let decoder = PropertyListDecoder()
  return try decoder.decode([String:String].self, from: data)
}

func write(dict: [String:String])throws {
  let encoder = PropertyListEncoder()
  let data = try encoder.encode(dict)
  try data.write(to: url)
}

func readNoError(url: URL) -> [String:String]? {
  guard let data = try? Data(contentsOf: url) else { return nil }
  let decoder = PropertyListDecoder()
  return try? decoder.decode([String:String].self, from: data)
}

func writeNoError(dict: [String:String]) -> Bool {
  let encoder = PropertyListEncoder()
  do {
    let data = try encoder.encode(dict)
    try data.write(to: url)
  } catch {
    return false
  }
  return true
}

@Daniel_Mullenborn’s answer is the general answer for 1. and 2. (But @eskimo’s caveat regarding the specific path is correct.)

The standard and core libraries are basically the same on all platforms, and they are where all the functionality from @Daniel_Mullenborn’s examples come from. It should work on all platforms that Swift supports, which are macOS, Linux, iOS, watchOS and tvOS. Android and Windows support is currently a work in progress, so while everything should eventually work, sometimes bits and pieces are still missing, and it is far more complicated to get Swift set up on them in the first place.

But the user interface is not part of Swift, so it varies heavily depending on the platform. You need a Swift‐enabled user interface library to do this:

  1. Show some lines of this file, for example, on text field in a window.

Since you are dealing with macOS, the answer for that is to look into AppKit (or any day now SwiftUI will be released), which are both easy to use. But if you were wanting to use user interface elements on the Windows operating system, then I cannot even guarantee that it is even possible yet, let alone explain how to do it.

Your example doesn't work, I have similar question how to write in a plist file.

Someone says that the Bundle.main.path can read data, but it can not write ,so I use file manager and encode to write ,but is doesn't work also, could you help me to look?

my code:

  <?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>currentChapter</key>
    <string>2</string>
    <key>currentLine</key>
    <string>2</string>
    <key>bookname</key>
    <string>ExcelBible</string>
</dict>
</plist>

let currentChapter = "10"
let currentLine = "10"
let nameOfBook = "WordBible"

let readData = [currentChapter, currentLine, nameOfBook]
//

let dataFilePaths = FileManager.default.urls(for: .documentDirectory,
                                             in: .userDomainMask)[0].appendingPathComponent("lineData.plist")

let data = try PropertyListEncoder().encode(readData)

try? data.write(to: dataFilePaths, options: Data.WritingOptions.atomic)

I’m going to recommend that you start a new thread for this; the problem you’re having is very unlikely to be related to the one that tripped up Wargadex.

While you’re doing this, please expand on “doesn't work”. Does it not compile? Fail with an error? Crash? Produce the wrong results?

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Thank you very much.

I will try it today and I am going to develop a view to test it, instead fo playground.

and I updated my MacOS and Xcode yesterday .

Yes, my mistake, doesn't work means that, the code executed ,but the plist file doesn't change its value, there is no fail or error.

I am new, I need time to get progress. ;-)