How to observe shared app groups file changed
我有在我的应用程序和扩展之间共享的文件:
从扩展名:
写入文件
1 2 3 4 5 6 7 8 9 10 11 12 13 | func writeToFile() { let file ="file.txt" let text ="data" //just a text let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:"group.com.ml.test.apps")! let fileURL = dir.appendingPathComponent(file) do { try text.write(to: fileURL, atomically: false, encoding: .utf8) } catch {/* error handling here */} } |
从应用程序中读取:
1 2 3 4 5 6 7 8 9 10 11 12 | func readFromFile() { let file ="file.txt" let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:"group.com.ml.test.apps")! let fileURL = dir.appendingPathComponent(file) do { let text2 = try String(contentsOf: fileURL, encoding: .utf8) NSLog("Dan: \\(text2)") } catch {/* error handling here */} } |
我的问题是如何观察该文件的更改。万一扩展名写了它并更改了数据,那么应用程序将获得通知更改并读取文件。
这是一个基于用法
通过Xcode 11.4 / iOS 13.4测试
1)应用部分。这是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | class ViewController: UIViewController, NSFilePresenter { var presentedItemURL: URL? var presentedItemOperationQueue: OperationQueue = OperationQueue.main @IBOutlet weak var userNameField: UILabel! func presentedItemDidChange() { // posted on changed existed file only readFromFile() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // register for presentedItemDidChange work NSFileCoordinator.addFilePresenter(self) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // unregister - required !! NSFileCoordinator.removeFilePresenter(self) } override func viewDidLoad() { super.viewDidLoad() let file ="file.txt" let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:"group.com.test.apps")! presentedItemURL = dir.appendingPathComponent(file) readFromFile() // read previously stored data } private func readFromFile() { let coordinator = NSFileCoordinator(filePresenter: self) coordinator.coordinate(readingItemAt: presentedItemURL!, options: [], error: nil) { url in if let text2 = try? String(contentsOf: url, encoding: .utf8) { userNameField.text = text2 // demo label in view for test } else { userNameField.text ="<no text>" //just initial creation of file needed to observe following changes coordinator.coordinate(writingItemAt: presentedItemURL!, options: .forReplacing, error: nil) { url in do { try"".write(to: url, atomically: false, encoding: .utf8) } catch { print("writing failed") } } } } } } |
2)扩展部分(具有一个按钮的演示的简单Today扩展)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class TodayViewController: UIViewController, NCWidgetProviding, NSFilePresenter { var presentedItemURL: URL? var presentedItemOperationQueue: OperationQueue = OperationQueue.main override func viewDidLoad() { super.viewDidLoad() let file ="file.txt" let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:"group.com.test.apps")! presentedItemURL = dir.appendingPathComponent(file) } @IBAction func post(_ sender: Any) { // action on button in extension writeToFile() } func writeToFile() { let text ="new data" //just a text let coordinator = NSFileCoordinator(filePresenter: self) coordinator.coordinate(writingItemAt: presentedItemURL!, options: .forReplacing, error: nil) { url in do { try text.write(to: url, atomically: false, encoding: .utf8) } catch { print("writing failed") } } } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { completionHandler(NCUpdateResult.newData) } } |