Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

CTMIME_SinglePart attachment issue #70

Closed
IacobRazvan opened this Issue Jan 30, 2013 · 12 comments

Comments

Projects
None yet
3 participants

I have an iOS app that uses MailCore. I want to detect the attachment of an email, and it does not seem to work all the time. For example the email has an .rtf file attached to it.
When the CTMIME_SinglePart structure is initialized in initWithMIMEStruct, my file is detected in the following condition:
NSString* lowercaseName = [self.filename lowercaseString];
if([lowercaseName hasSuffix:@".xls"] ||
....
[lowercaseName hasSuffix:@".rtf"] ||
...
self.attached = YES;
}
But whenever I call the following method, the file seems not to be found:

  • (NSArray *)attachments {
    NSMutableArray *attachments = [NSMutableArray array];

    CTMIME_Enumerator *enumerator = [myParsedMIME mimeEnumerator];
    CTMIME *mime;
    while ((mime = [enumerator nextObject])) {
    if ([mime isKindOfClass:[CTMIME_SinglePart class]]) {
    CTMIME_SinglePart *singlePart = (CTMIME_SinglePart *)mime;
    if (singlePart.attached) {
    CTBareAttachment *attach = [[CTBareAttachment alloc]
    initWithMIMESinglePart:singlePart];
    [attachments addObject:attach];
    [attach release];
    }
    }
    }
    return attachments;
    }

So far it worked only when I had a .wav file attached to the email. Could you please let me know how to fix this?

Alger commented Jan 30, 2013

I also have this issue, it seems that only happend on iPhone 5 device, and iPhone 4, 4s work fine

As far as I've tested, the bug occured on the following devices:
iPhone 3GS - iOS 5.1.1
iPhone 4 - iOS 6.0

Since the (NSArray *)attachments method does not return the same output for different devices, this is clearly a bug that needs fixing

Owner

mronge commented Jan 30, 2013

If you step through the attachments method with the debugger, do you see it iterating over the attachment?

I'm wondering which of these is failing:

  1. The attachment isn't in the list of mime types that the enumerator goes over
  2. The code below failing, and it isn't a CTMIME_SinglePart

if ([mime isKindOfClass:[CTMIME_SinglePart class]]) {

  1. Or this code below is failing and it isn't marked as attached.

if (singlePart.attached

If you step in with the debugger what do you see?

Thanks!

On Jan 30, 2013, at 2:33 AM, IacobRazvan notifications@github.com wrote:

I have an iOS app that uses MailCore. I want to detect the attachment of an email, and it does not seem to work all the time. For example the email has an .rtf file attached to it.
When the CTMIME_SinglePart structure is initialized in initWithMIMEStruct, my file is detected in the following condition:
NSString* lowercaseName = [self.filename lowercaseString];
if([lowercaseName hasSuffix:@".xls"] ||
....
[lowercaseName hasSuffix:@".rtf"] ||
...
self.attached = YES;
}
But whenever I call the following method, the file seems not to be found:

• (NSArray *)attachments {
NSMutableArray *attachments = [NSMutableArray array];

CTMIME_Enumerator *enumerator = [myParsedMIME mimeEnumerator];
CTMIME *mime;
while ((mime = [enumerator nextObject])) {
if ([mime isKindOfClass:[CTMIME_SinglePart class]]) {
CTMIME_SinglePart *singlePart = (CTMIME_SinglePart *)mime;
if (singlePart.attached) {
CTBareAttachment *attach = [[CTBareAttachment alloc]
initWithMIMESinglePart:singlePart];
[attachments addObject:attach];
[attach release];
}
}
}
return attachments;
}

So far it worked only when I had a .wav file attached to the email. Could you please let me know how to fix this?


Reply to this email directly or view it on GitHub.

Alger commented Jan 31, 2013

I cannot reproduce on my side, it just report from user

IacobRazvan ,Could you give us more info of this issue

Ok, so here are a few steps, starting from creating the MIMEStruct.

===== Class: CTMIME_SinglePart.m =====

method called: - (id)initWithMIMEStruct:(struct mailmime *)mime
forMessage:(struct mailmessage *)message {

condition passed:
if([lowercaseName hasSuffix:@".rtf"] {

(CTMIME_SinglePart *) $1 = 0x1f55ea00 <CTMIME_SinglePart: 0x1f55ea00>

===== The follwoing methods are called: =====
(NSString *)body {
(BOOL)fetchBodyStructure {

===== Class: CTMIME_Factory.m =====

method called: + (CTMIME *)createMIMEWithMIMEStruct:(struct mailmime *)mime
forMessage:(struct mailmessage *)message {

===== Class: CTMIME_MultiPart.m =====

method called: - (id)initWithMIMEStruct:(struct mailmime *)mime forMessage:(struct mailmessage *)message {

        CTMIME *content = [CTMIMEFactory createMIMEWithMIMEStruct:clist_content(cur) forMessage:message];

condition passed:
if (content != nil) {
[myContentList addObject:content];
}

(CTMIME *) $2 = 0x1f55ea00 <CTMIME_SinglePart: 0x1f55ea00>

===== Class: CTMIME_MessagePart.m =====

method called: - (id)initWithMIMEStruct:(struct mailmime *)mime
forMessage:(struct mailmessage *)message {

===== Class: CTMIME_CoreMessage.m =====

method called: - (NSArray *)attachments {

po enumerator.allObjects
(NSArray *) (
CTMIME_MessagePart: 0x2319f3e0
CTMIME_TextPart: 0x2319f2d0
)

condition passed:
if ([mime isKindOfClass:[CTMIME_SinglePart class]]) {
po singlePart
(CTMIME_SinglePart *) $24 = 0x2fd93ca0

condition not passed:
if (singlePart.attached) {

}

@IacobRazvan IacobRazvan reopened this Jan 31, 2013

Alger commented Jan 31, 2013

LacobRazvan, Could you debug it why the value of attached has been changed before get it in method "- (NSArray *)attachments", the bad thing is that I cannot reproduce on my side.:)

Thanks

Ok so the last place where I could trace the CTMIME_SinglePart as having the attached property YES, was in:
CTCoreMessage.m

  • (void)_buildUpBodyText:(CTMIME *)mime result:(NSMutableString *)result {
    (CTMIME *) $6 = 0x26a908b0 <CTMIME_MessagePart: 0x26a908b0>

It passes the condition:
if ([mime isKindOfClass:[CTMIME_MultiPart class]]) {

po mime content $14 = 0x26a91990 <__NSArrayM 0x26a91990>(
CTMIME_MultiPart: 0x1f992d70,
CTMIME_SinglePart: 0x26a98060
)

po [mime content] lastObject $15 = 0x26a98060 CTMIME_SinglePart: 0x26a98060
po (int) [[mime content] lastObject] attached $16 = 1 [no Objective-C description available]

I noticed that before accessing the CTCoreMessage object's attachments method, I first have a check to see if the (CTCoreMessage_)msg.body and (CTCoreMessage_)msg.htmlBody contain anything (I need to remove some html tags left in the body). And when I access msg.body, the method

  • (void)_buildUpBodyText:(CTMIME *)mime result:(NSMutableString *)result {
    is called again. After that I call the attachments method, and I get the previously described bug.

Could this be the cause of the issue? Accessing the msg.body before msg.attachments?

Yes. I can confirm now that the issue occurs when accessing (CTCoreMessage_)msg.body or (CTCoreMessage_)msg.htmlBody before msg.attachments. Now it can see my attachments if I first call msg.attachments, but is this just a fix that I localy need to do, or will this issue need to be investigated by the MailCore team?

Owner

mronge commented Jan 31, 2013

Yea that sounds like a potential bug in MailCore

@mronge mronge reopened this Jan 31, 2013

After further investigation, I think the issue was on my side, and not because of MailCore. As I was saying I had to filter the html body because it had some html alt tags left in it (this may be a bug of MailCore). After that I was doing the following:
[(CTCoreMessage )msg setBody: (NSString)filteredBody]
So this was causing the issue of not seeing afterwards my attachments. So I avoided doing this anymore.

But I do have an issue: I have to send an email with an attachment, and I want to format it's html body to include some paragraph styles. This is a part of the code I am using:

CTCoreMessage *msg = [[CTCoreMessage alloc] init];
[msg setTo:[NSSet setWithObject:emailReceiver]];
[msg setFrom:[NSSet setWithObject:emailSender]];
[msg setHTMLBody:emailBody];

NSData *attachment = [[NSData alloc] initWithContentsOfFile:voicemailPath];
[msg addAttachment:[[CTCoreAttachment alloc] initWithData:attachment contentType:@"wav" filename:NSLocalizedString(@"EmailAttachmentFile",@"Dictation_recording.wav")]];
}

Do I have to set a mime type for this message before adding it's htmlBody and attachments?

The email is being sent fine, along with it's attachment, but whenever I check for this email in my app, again it doesn't detect any attachments. This is because I set the htmlBody of the CTCoreMessage. Can you tell me if I am doing something wrong, or how can I do this feature so that it works fine?

Owner

mronge commented Feb 1, 2013

When receiving email I would recommend taking the HTML body and saving the modified version to some location outside of CTCoreMessage.

When you aren't detecting attachments, is that from a round trip to the server? Like you send the message, and then the IMAP fetch code downloads the message from the Inbox and it has no attachments?

On Feb 1, 2013, at 3:16 AM, IacobRazvan notifications@github.com wrote:

After further investigation, I think the issue was on my side, and not because of MailCore. As I was saying I had to filter the html body because it had some html alt tags left in it (this may be a bug of MailCore). After that I was doing the following:
[(CTCoreMessage )msg setBody: (NSString)filteredBody]
So this was causing the issue of not seeing afterwards my attachments.

But I do have an issue: I have to send an email with an attachment, and I want to format it's html body to include some paragraph styles. This is a part of the code I am using:

CTCoreMessage *msg = [[CTCoreMessage alloc] init];
[msg setTo:[NSSet setWithObject:emailReceiver]];
[msg setFrom:[NSSet setWithObject:emailSender]];
[msg setHTMLBody:emailBody];

NSData *attachment = [[NSData alloc] initWithContentsOfFile:voicemailPath];
[msg addAttachment:[[CTCoreAttachment alloc] initWithData:attachment contentType:@"wav" filename:NSLocalizedString(@"EmailAttachmentFile",@"Dictation_recording.wav")]];
}

The email is being sent fine, along with it's attachment, but whenever I check for this email in my app, again it doesn't detect any attachments. This is because I set the htmlBody of the CTCoreMessage. Can you tell me if I am doing something wrong, or how can I do this feature so that it works fine?


Reply to this email directly or view it on GitHub.

The method (NSArray *)attachments is returning an empty array when I want to send an email from the app, and I set the htmlBody property. It does send the email and the attachments correctly, I checked it on the email client, but whenever checking it in the app, it doesn't detect any attachments. Do I have to set the MIME for the CTCoreMessage object before? Do you have maybe a working example of sending an email and setting it's htmlBody?

@mronge mronge closed this Mar 14, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment