2

我有一个可可应用程序,我想在其中接受来自 mail.app 的电子邮件,并将其拖入应用程序的主窗口。我在我的 applicationDidFinishLaunching 中有:

[_window registerForDraggedTypes:
    [NSArray arrayWithObjects:
       NSFilenamesPboardType,
      (NSString *)kPasteboardTypeFileURLPromise, nil]]; //kUTTypeData
[_window setDelegate:(id) self];

这很好用,我可以在 performDragOperation 中收到一个文档:使用

NSArray * files =  [sender namesOfPromisedFilesDroppedAtDestination:url];

但是,这只让我一个接一个地拖动电子邮件。如果我标记了几封电子邮件,一切似乎都很好,直到我放弃,然后什么也没有发生。performDragOperation 甚至没有被调用。

我试图将 kUTTypeData 添加到 registerForDraggedTypes...,然后我调用了 performDragOperation...,但是我不能使用 namesOfPromisedFilesDroppedAtDestination:url,因为它返回一个 nil 指针。

当我将 kUTTypeData 包含在寄存器中时...我将其包含在 performDragOperation 中以查看拖动中的类型:

pboard = [sender draggingPasteboard];
NSLog(@"perform drag entered, %@", [pboard types]);

结果如下:

2013-07-25 15:09:50.771 BO2ICAL[1672:303] perform drag entered, (
"dyn.ah62d4rv4gu8y4zvanr41a3pwfz30n25wqz4ca5pfsr30c35feb4he2pssrxgn6vasbu1g7dfqm10c6xeeb4hw6df",
"MV Super-secret message transfer pasteboard type",
"dyn.ah62d4rv4gu8zg7puqz3c465fqr3gn7bakf41k55rqf4g86vasbu1g7dfqm10c6xeeb4hw6df",
"Super-secret Automator pasteboard type"
)

虽然单个电子邮件的列表是:

2013-07-25 15:14:30.096 BO2ICAL[1672:303] perform drag entered, ( "dyn.ah62d4rv4gu8y4zvanr41a3pwfz30n25wqz4ca5pfsr30c35feb4he2pssrxgn6vasbu1g7dfqm10c6xeeb4hw6df", "MV Super-secret message transfer pasteboard type", "dyn.ah62d4rv4gu8zg7puqz3c465fqr3gn7bakf41k55rqf4g86vasbu1g7dfqm10c6xeeb4hw6df", "Super-secret Automator pasteboard type", "dyn.ah62d4rv4gu8yc6durvwwa3xmrvw1gkdusm1044pxqyuha2pxsvw0e55bsmwca7d3sbwu", "Apple files promise pasteboard type", "public.url", "CorePasteboardFlavorType 0x75726C20", "dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu", "Apple URL pasteboard type", "public.url-name", " CorePasteboardFlavorType 0x75726C6E", "com.apple.pasteboard.promised-file-content-type", "com.apple.pasteboard.promised-file-url", "dyn.ah62d4rv4gu8y6y4usm1044pxqzb085xyqz1hk64uqm10c6xenv61a3k", NSPromiseContentsPboardType)

有没有人有任何建议如何正确地做到这一点以接受多封电子邮件?

4

1 回答 1

2

我找到了解决方案。我发现“kUTTypeData”模式下提供的数据给了我足够的数据,可以直接从mail.app邮箱中抓取文件。

在 mbox 文件夹中,有一个由一长串数字和破折号组成的文件夹,在邮箱层次结构中的任何地方都没有这个名字的踪迹,但是由于它只包含这个文件夹和一个 info.plist 文件,所以我使用这个函数来获取该名称:更新:实施正则表达式检查,因为该文件夹有时包含可能具有更长名称的子邮箱...

-(NSString*)FindCodedFolderInMailbox:(NSString*)mailboxpath {

     NSString *uuid_regexp = @"[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}";
     NSPredicate *uuid_test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", uuid_regexp];

     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSArray *fileList = [fileManager contentsOfDirectoryAtPath:mailboxpath error:nil];
     for (NSString * file in fileList) {
         if ([uuid_test evaluateWithObject: file]){
             return file;
         }
     }
     return nil;
}

然后我发现没有“NSPromiseContentsPboardType”的部分,而是“Super-secret Automator 粘贴板类型”,我写了以下部分(我打算删除一些 NSLog 条目,但这里是:

} else if ( [[pboard types] containsObject:@"Super-secret Automator pasteboard type"] ) {

     NSFileManager *fileManager = [NSFileManager defaultManager];
     // Create the URL for the destination folder and ensure it exists. 
     NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
     NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"documents"];
     BOOL isDir;
     if (!([fileManager fileExistsAtPath:[url path] isDirectory:&isDir] && isDir)) {
         NSError * error = nil;
         [ fileManager createDirectoryAtURL:url withIntermediateDirectories: YES attributes:nil error:&error];
         if (error) {
             [[NSApplication sharedApplication] presentError:error];
         }
     }
     BOOL ok = false;

  // locate the mailbox path....
    NSString *mailboxpath = [pboard stringForType:@"MV Super-secret message transfer pasteboard type"];
    NSLog(@"Mailboxpath: %@", mailboxpath);

    NSString * codedFolder = [self FindCodedFolderInMailbox:mailboxpath];
    if (codedFolder) {
        NSString * codedpath = [NSString stringWithFormat:@"file://%@/%@/Data", mailboxpath, codedFolder];
        NSURL * mb1 = [NSURL URLWithString:codedpath];
        NSLog(@"Directory:%@", mb1);
        NSArray *msgArray = [pboard propertyListForType:@"Super-secret Automator pasteboard type"];
        if (msgArray) {
            for (NSDictionary *msg in msgArray) {

                // Locate the message....
                NSNumber * msgID = [msg valueForKey:@"id"];
                NSLog(@"Melding(%@):%@", msgID, msg);
                NSString * filename = [NSString stringWithFormat:@"%@.emlx", msgID];

                // second and first letter of id
                NSString * idSec = [[msgID stringValue]substringWithRange:(NSRange){1, 1}];
                NSString * idFirst = [[msgID stringValue]substringWithRange:(NSRange){0, 1}];
                NSString * subpath = [NSString stringWithFormat:@"%@/%@/Messages/%@",idSec, idFirst,  filename];

                NSURL * thisFilePath = [mb1 URLByAppendingPathComponent:subpath];


                if ([fileManager fileExistsAtPath:[thisFilePath path]]) {

                    NSURL *destpath = [url URLByAppendingPathComponent:filename];

                    NSError * error = nil;
                    [fileManager copyItemAtURL:thisFilePath toURL:destpath error:&error];
                    if (error) {
                        [[NSApplication sharedApplication]presentError:error];
                    } else {
                        [self ParseEmlMessageforPath:[destpath path] filename:filename];

                    }


                }

            }


        }

    }

现在我们开始.... :-)

于 2013-07-26T20:51:31.667 回答