我正在尝试观察一个文件夹,以查看Mac OS上该文件夹中是否创建,修改/删除了文件等。我已经读到我要使用的是文件系统事件,但是我无法使我的代码正常工作。
我曾尝试阅读docs at apple并阅读关于stackoverflow的不同文章,但我发现在swift 4和xcode 10上似乎没有任何作用。
init(path: String) {
let allocator: CFAllocator? = kCFAllocatorDefault
// Create FSEventStream and return valid FSEventStreamRef
// Alias FSEventStreamCallback - CFunction
typealias FSEventStreamCallback = @convention(c) (ConstFSEventStreamRef, UnsafeMutableRawPointer?, Int, UnsafeMutableRawPointer, UnsafePointer<FSEventStreamEventFlags>, UnsafePointer<FSEventStreamEventId>) -> Void
let callback: FSEventStreamCallback = {
(streamRef, clientCallBackInfo, numEvents, eventPaths, eventFlags, eventIds) -> Void in
print ("changed")
// handle file event
}
let context: UnsafeMutablePointer<FSEventStreamContext>? = nil
let pathsToWatch: CFArray = [NSHomeDirectory() + path] as CFArray
let sinceWhen: FSEventStreamEventId = UInt64(kFSEventStreamEventIdSinceNow)
let latency: CFTimeInterval = 1.0
let flags: FSEventStreamCreateFlags = UInt32(kFSEventStreamCreateFlagNone)
let eventStream = FSEventStreamCreate(
allocator,
callback,
context,
pathsToWatch,
sinceWhen,
latency,
flags
)
FSEventStreamScheduleWithRunLoop(eventStream, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode as! CFString)
FSEventStreamStart(eventStream!)
}
我要么收到错误
Value of optional type 'FSEventStreamRef?' (aka 'Optional<OpaquePointer>') must be unwrapped to a value of type 'FSEventStreamRef' (aka 'OpaquePointer')
当我尝试构建或
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
在运行时,如果我添加“!”到“ eventStream”
我需要更改使其运行吗?
答案 0 :(得分:0)
eventStream
必须解开-最好带有可选的绑定,例如
guard let eventStream = FSEventStreamCreate(...) else {
// handle error ...
}
但是实际上导致程序崩溃的是强制转换
FSEventStreamScheduleWithRunLoop(..., CFRunLoopMode.defaultMode as! CFString)
CFRunLoopMode
不是CFString
,因此强制as! CFString
失败。它是一个struct CFRunLoopMode: RawRepresentable
,基础CFString
是通过rawValue
属性获得的:
FSEventStreamScheduleWithRunLoop(..., CFRunLoopMode.defaultMode.rawValue)
备注: typealias FSEventStreamCallback
已在Core Services框架中定义,因此无需在类中重复该定义。