我正在研究支持iTunes文件共享功能的iOS项目。目标是实时跟踪传入/更改的数据。

我正在使用(Apple的示例代码中的(kinda修改的)DirectoryWatcher
还尝试了this source code

数据为NSBundle(* .bundle),某些捆绑包的大小在100-500 MB之间,具体取决于其内容以及一些视频/音频内容。捆绑软件中包含基于xml的描述 rune 件。

问题是在数据刚刚开始复制时之上的任何上述代码都会触发通知或其他任何事件,但在时,复制/更改/删除过程完全完成时,则不会发出通知。

接下来尝试:

检查文件属性:

NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
BOOL fileBusy = [[fileAttrs objectForKey:NSFileBusy] boolValue];

寻找fileSize的变化:
dispatch_async(_checkQueue, ^{
    for (NSURL *contURL in tempBundleURLs) {
        NSInteger lastSize = 0;
        NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
        NSInteger fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

        do {
            lastSize = fileSize;
            [NSThread sleepForTimeInterval:1];

            fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
            fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

            NSLog(@"doing job");
        } while (lastSize != fileSize);

        NSLog(@"next job");
    }
);

还有其他解决方案吗?

上面的解决方案非常适合bin文件,但不适用于.bundle(因为.bundle文件实际上是目录)。为了使其与.bundle一起使用,您应该迭代.bundle中的每个文件

最佳答案

您可以使用GCD的调度源机制-使用它可以观察特定的系统事件(在这种情况下,这是vnode类型的事件,因为您正在使用文件系统)。
要为特定目录设置观察者,我使用了如下代码:

- (dispatch_source_t) fileSystemDispatchSourceAtPath:(NSString*) path
{
    int fileDescr = open([path fileSystemRepresentation], O_EVTONLY);// observe file system events for particular path - you can pass here Documents directory path
    //observer queue is my private dispatch_queue_t object
    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileDescr, DISPATCH_VNODE_ATTRIB| DISPATCH_VNODE_WRITE|DISPATCH_VNODE_LINK|DISPATCH_VNODE_EXTEND, observerQueue);// create dispatch_source object to observe vnode events
    dispatch_source_set_registration_handler(source, ^{
        NSLog(@"registered for observation");
        //event handler is called each time file system event of selected type (DISPATCH_VNODE_*) has occurred
        dispatch_source_set_event_handler(source, ^{

            dispatch_source_vnode_flags_t flags = dispatch_source_get_data(source);//obtain flags
            NSLog(@"%lu",flags);

            if(flags & DISPATCH_VNODE_WRITE)//flag is set to DISPATCH_VNODE_WRITE every time data is appended to file
            {
                NSLog(@"DISPATCH_VNODE_WRITE");
                NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
                float size = [[dict valueForKey:NSFileSize] floatValue];
                NSLog(@"%f",size);
            }
            if(flags & DISPATCH_VNODE_ATTRIB)//this flag is passed when file is completely written.
            {
                NSLog(@"DISPATCH_VNODE_ATTRIB");
                dispatch_source_cancel(source);
            }
            if(flags & DISPATCH_VNODE_LINK)
            {
                NSLog(@"DISPATCH_VNODE_LINK");
            }
            if(flags & DISPATCH_VNODE_EXTEND)
            {
                NSLog(@"DISPATCH_VNODE_EXTEND");
            }
            NSLog(@"file = %@",path);
            NSLog(@"\n\n");
        });

        dispatch_source_set_cancel_handler(source, ^{
            close(fileDescr);
        });
    });

    //we have to resume dispatch_objects
    dispatch_resume(source);

    return source;
}

关于objective-c - iTunes文件共享应用程序: realtime monitoring for incoming datas,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9731521/

10-11 22:44
查看更多