変数 'a'が作成されています。たとえば、デスクトップ上のテキストファイルの値です。私はデータを連続的に読んで、私のアプリケーションに 'a'の値を表示したい。Swift:ユーザー入力なしでテキストファイルまたはサーバーから連続してデータを読み取る方法
テキストファイルから値を変更しても、アプリケーションに自動的に反映されるはずです。
提案がありますか?
私はあなたがファイルを監視するために、GCDの派遣ソースを使用することができスウィフト2.2
変数 'a'が作成されています。たとえば、デスクトップ上のテキストファイルの値です。私はデータを連続的に読んで、私のアプリケーションに 'a'の値を表示したい。Swift:ユーザー入力なしでテキストファイルまたはサーバーから連続してデータを読み取る方法
テキストファイルから値を変更しても、アプリケーションに自動的に反映されるはずです。
提案がありますか?
私はあなたがファイルを監視するために、GCDの派遣ソースを使用することができスウィフト2.2
を使用しています。以下は、ファイルを監視し、更新のたびにファイルの内容でNSTextView
を更新する簡単な例です。
class ViewController: NSViewController {
@IBOutlet var textView: NSTextView!
// Create a dispatch_source_t to monitor the file
func dispatchSoureForFile(at path: String) -> dispatch_source_t? {
let fileHandle = open(path.cStringUsingEncoding(NSUTF8StringEncoding)!, O_RDONLY)
// Cannot open file
guard fileHandle != -1 else {
return nil
}
// The queue where the event handler will execute. Don't set to the main queue
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
// The events we are interested in
let mask = DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND
return dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, UInt(fileHandle), mask, queue)
}
// The function to use for monitoring a file
func startMonitoringFile(at path: String) {
guard let dispatchSource = dispatchSoureForFile(at: path) else {
print("Cannot create dispatch source to monitor file at '\(path)'")
return
}
let eventHandler = {
let data = dispatch_source_get_data(dispatchSource)
// Tell what change happened to the file. Delete it if you want
if data & DISPATCH_VNODE_WRITE != 0 {
print("File is written to")
}
if data & DISPATCH_VNODE_EXTEND != 0 {
print("File is extended to")
}
if data & DISPATCH_VNODE_DELETE != 0 {
print("File is deleted")
}
// Sometimes the old version of the file is deleted before the new version is written
// to disk. This happens when you call `writeToFile(_, atomically: true)` for example.
// In that case, we want to stop monitoring at the old node and start at the new node
if data & DISPATCH_VNODE_DELETE == 1 {
dispatch_source_cancel(dispatchSource)
self.startMonitoringFile(at: path)
return
}
// Always update the GUI from the main queue
let fileContent = try! String(contentsOfFile: path)
dispatch_async(dispatch_get_main_queue()) {
self.textView.string = fileContent
}
}
// When we stop monitoring a vnode, close the file handle
let cancelHandler = {
let fileHandle = dispatch_source_get_handle(dispatchSource)
close(Int32(fileHandle))
}
dispatch_source_set_registration_handler(dispatchSource, eventHandler)
dispatch_source_set_event_handler(dispatchSource, eventHandler)
dispatch_source_set_cancel_handler(dispatchSource, cancelHandler)
dispatch_resume(dispatchSource)
}
override func viewDidLoad() {
super.viewDidLoad()
self.startMonitoringFile(at: "/path/to/file.txt")
}
}
DISPATCH_VNODE_EXTEND
イベントをトリガーするために、あなたはターミナルでこれを試すことができます。
echo "Hello world" >> /path/to/file.txt
ありがとう、あなたにチェックして戻ってきます。 – Coding4Life
私は非常によく似たユースケースのために(スウィフト3.xの中で)動作するように次のコードを得ることができました。それが役に立てば幸い。
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(ViewController.commandOutputNotification(_:)),
name: NSNotification.Name.NSFileHandleDataAvailable,
object: nil)
self.startTasks()
}
func startTasks() {
self.task = Process()
self.task!.terminationHandler = self.commandTerminationHandler
let argumentsString = "tail -n 1 -f /path/to/file/file.log"
self.task!.launchPath = "/bin/sh"
self.task!.arguments = ["-c", argumentsString]
let pipe = Pipe()
task!.standardOutput = pipe
task!.standardError = pipe
pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
task!.launch()
}
func commandTerminationHandler(_ task: Process) -> Void {
// TODO: finish this
}
func commandOutputNotification(_ notification: Notification) {
let fileHandle = notification.object as! FileHandle
let data = fileHandle.availableData
if data.count > 0 {
processLogData(data:(String.init(data: data, encoding: String.Encoding.utf8)))
fileHandle.waitForDataInBackgroundAndNotify()
}
}
func processLogData(data:String?) {
// Handle data String
}
このファイルを正しく開くと、これは自動的に発生します。 NSDocumentは、ファイルが変更されたために再読み込みする必要があることを伝えます。 – matt
ここをクリックしてください:http://codekea.com/2EgRdM8Mmb5R/real-time-nstask-output-to-nstextview-with-swift.html – Woodstock