首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >iPhone /Documents目录变更的通知

iPhone /Documents目录变更的通知
EN

Stack Overflow用户
提问于 2010-07-06 03:48:30
回答 4查看 8.3K关注 0票数 18

我们有一个使用文件共享的应用程序。UIFileSharingEnable已经设置好了等等,看起来一切都很好,但是我正在寻找在iPhone端添加/删除文件时的某种通知。有人能给点建议吗?

提前干杯。

EN

回答 4

Stack Overflow用户

发布于 2010-07-07 02:58:40

苹果开发者论坛上的This thread可能会引起人们的兴趣,其中建议您在自己的线程中运行kqueue,跟踪应用程序的Documents文件夹。

一位苹果技术人员随后发布了一些sample code here

代码语言:javascript
复制
- (void)kqueueFired
{
    int             kq;
    struct kevent   event;
    struct timespec timeout = { 0, 0 };
    int             eventCount;

    kq = CFFileDescriptorGetNativeDescriptor(self->_kqRef);
    assert(kq >= 0);

    eventCount = kevent(kq, NULL, 0, &event, 1, &timeout);
    assert( (eventCount >= 0) && (eventCount < 2) );

    if (eventCount == 1) {
        NSLog(@"dir changed");
    }    

    CFFileDescriptorEnableCallBacks(self->_kqRef, kCFFileDescriptorReadCallBack);
}

static void KQCallback(CFFileDescriptorRef kqRef, CFOptionFlags callBackTypes, void *info)
{
    ViewController *    obj;

    obj = (ViewController *) info;
    assert([obj isKindOfClass:[ViewController class]]);
    assert(kqRef == obj->_kqRef);
    assert(callBackTypes == kCFFileDescriptorReadCallBack);

    [obj kqueueFired];
}

- (IBAction)testAction:(id)sender
{
    #pragma unused(sender)
    NSString *              docPath;
    int                     dirFD;
    int                     kq;
    int                     retVal;
    struct kevent           eventToAdd;
    CFFileDescriptorContext context = { 0, self, NULL, NULL, NULL };
    CFRunLoopSourceRef      rls;

    docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    assert(docPath != 0);

    NSLog(@"%@", docPath);

    dirFD = open([docPath fileSystemRepresentation], O_EVTONLY);
    assert(dirFD >= 0);

    kq = kqueue();
    assert(kq >= 0);

    eventToAdd.ident  = dirFD;
    eventToAdd.filter = EVFILT_VNODE;
    eventToAdd.flags  = EV_ADD | EV_CLEAR;
    eventToAdd.fflags = NOTE_WRITE;
    eventToAdd.data   = 0;
    eventToAdd.udata  = NULL;

    retVal = kevent(kq, &eventToAdd, 1, NULL, 0, NULL);
    assert(retVal == 0);

    assert(self->_kqRef == NULL);

    self->_kqRef = CFFileDescriptorCreate(NULL, kq, true, KQCallback, &context);
    assert(self->_kqRef != NULL);

    rls = CFFileDescriptorCreateRunLoopSource(NULL, self->_kqRef, 0);
    assert(rls != NULL);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);

    CFRelease(rls);

    CFFileDescriptorEnableCallBacks(self->_kqRef, kCFFileDescriptorReadCallBack);
}
票数 23
EN

Stack Overflow用户

发布于 2013-12-06 20:02:56

这是一个使用中央调度中心的替代解决方案,它允许您从NSNotificationCenter接收文件更改通知:

将这些变量添加到类的接口中:

代码语言:javascript
复制
// Dispatch queue
dispatch_queue_t _dispatchQueue;

// A source of potential notifications
dispatch_source_t _source;

将以下代码添加到实现中:

代码语言:javascript
复制
    #define fileChangedNotification @"fileChangedNotification"

    // Get the path to the home directory
    NSString * homeDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

    // Create a new file descriptor - we need to convert the NSString to a char * i.e. C style string
    int filedes = open([homeDirectory cStringUsingEncoding:NSASCIIStringEncoding], O_EVTONLY);

    // Create a dispatch queue - when a file changes the event will be sent to this queue
    _dispatchQueue = dispatch_queue_create("FileMonitorQueue", 0);

    // Create a GCD source. This will monitor the file descriptor to see if a write command is detected
    // The following options are available

    /*!
     * @typedef dispatch_source_vnode_flags_t
     * Type of dispatch_source_vnode flags
     *
     * @constant DISPATCH_VNODE_DELETE
     * The filesystem object was deleted from the namespace.
     *
     * @constant DISPATCH_VNODE_WRITE
     * The filesystem object data changed.
     *
     * @constant DISPATCH_VNODE_EXTEND
     * The filesystem object changed in size.
     *
     * @constant DISPATCH_VNODE_ATTRIB
     * The filesystem object metadata changed.
     *
     * @constant DISPATCH_VNODE_LINK
     * The filesystem object link count changed.
     *
     * @constant DISPATCH_VNODE_RENAME
     * The filesystem object was renamed in the namespace.
     *
     * @constant DISPATCH_VNODE_REVOKE
     * The filesystem object was revoked.
     */

    // Write covers - adding a file, renaming a file and deleting a file...
    _source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,filedes,
                                                       DISPATCH_VNODE_WRITE,
                                                       _dispatchQueue);


    // This block will be called when teh file changes
    dispatch_source_set_event_handler(_source, ^(){
        // We call an NSNotification so the file can change can be detected anywhere
        [[NSNotificationCenter defaultCenter] postNotificationName:fileChangedNotification object:Nil];
    });

    // When we stop monitoring the file this will be called and it will close the file descriptor
    dispatch_source_set_cancel_handler(_source, ^() {
        close(filedes);
    });

    // Start monitoring the file...
    dispatch_resume(_source);

    //...

    // When we want to stop monitoring the file we call this
    //dispatch_source_cancel(source);


    // To recieve a notification about the file change we can use the NSNotificationCenter
    [[NSNotificationCenter defaultCenter] addObserverForName:fileChangedNotification object:Nil queue:Nil usingBlock:^(NSNotification * notification) {
        NSLog(@"File change detected!");
    }];
票数 16
EN

Stack Overflow用户

发布于 2012-10-06 21:18:22

老问题,但我遇到了包含目录监视器的this Apple code。请注意,它会在添加(或删除)文件时触发;这可能是在操作系统完成对文件的写入之前。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3181821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档