简体   繁体   English

MFMailComposeViewController:附加照片库中的图像

[英]MFMailComposeViewController: Attaching Images from Photo Gallery

I am having a bit of trouble attaching images from the Photo Gallery to an email. 将照片库中的图像附加到电子邮件时遇到麻烦。

Basically, one of the features of my application allow the user to take photos. 基本上,我的应用程序的功能之一允许用户拍照。 When they snap the shot, I record the URL Reference to the image in Core Data. 当他们拍摄快照时,我在Core Data中记录了指向图像的URL参考。 I understand that you have to go through the ALAssetRepresentation to get to the image. 我了解您必须通​​过ALAssetRepresentation才能获取图像。 I have this up and running within my application for when the user wants to review an image that they have taken. 当用户想要查看他们拍摄的图像时,我已经在我的应用程序中启动了该程序。

I am now attempting to allow the user to attach all of the photos taken for an event to an email. 我现在正试图允许用户将为事件拍摄的所有照片附加到电子邮件中。 While doing this, I iterate through the Core Data entity that stores the URL References, call a method that returns a UIImage from the ALAssetsLibrary and then attaches it using the NSData / UIImageJPEGRepresentation and MFMailComposeViewController / addAttachmentData methods. 在执行此操作时,我遍历存储URL引用的Core Data实体,调用从ALAssetsLibrary返回UIImage的方法,然后使用NSData / UIImageJPEGRepresentationMFMailComposeViewController / addAttachmentData方法将其附加。

Problem is: When the email is presented to the user, there are small blue squares representing the images and the image is not attached. 问题是:向用户显示电子邮件时,会有蓝色的小方块代表图像,而图像未附加。

Here is the code: 这是代码:

- (void)sendReportReport
{

    if ([MFMailComposeViewController canSendMail])
    {

        MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];

        mailer.mailComposeDelegate = self;

        [mailer setSubject:@"Log: Report"];

        NSArray *toRecipients = [NSArray arrayWithObjects:@"someone@someco.com", nil];
        [mailer setToRecipients:toRecipients];


        NSError *error;

        NSFetchRequest *fetchPhotos = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription 
                                       entityForName:@"Photo" inManagedObjectContext:__managedObjectContext];
        [fetchPhotos setEntity:entity];
        NSArray *fetchedPhotos = [__managedObjectContext executeFetchRequest:fetchPhotos error:&error];
        int counter;

        for (NSManagedObject *managedObject in fetchedPhotos ) {
            Photo *photo = (Photo *)managedObject;

//            UIImage *myImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png", counter++]];
            NSData *imageData = UIImageJPEGRepresentation([self getImage:photo.referenceURL], 0.5);
//            NSData *imageData = UIImagePNGRepresentation([self getImage:photo.referenceURL]);
//            [mailer addAttachmentData:imageData mimeType:@"image/jpeg" fileName:[NSString stringWithFormat:@"%i", counter]];  
            [mailer addAttachmentData:imageData mimeType:@"image/jpeg" fileName:[NSString stringWithFormat:@"a.jpg"]];  

            counter++;

        }


        NSString *emailBody = [self getEmailBody];

        [mailer setMessageBody:emailBody isHTML:NO];

        [self presentModalViewController:mailer animated:YES];

    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];

    }

}

and the method that returns the UIImage : 以及返回UIImage的方法:

#pragma mark - Get Photo from Asset Library
+ (ALAssetsLibrary *)defaultAssetsLibrary {
    static dispatch_once_t pred = 0;
    static ALAssetsLibrary *library = nil;
    dispatch_once(&pred, ^{
        library = [[ALAssetsLibrary alloc] init];
    });
    return library; 
}

- (UIImage *)getImage:(NSString *)URLReference
{

    __block UIImage *xPhoto = nil;

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        UIImage *xImage;

        // get the image
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullScreenImage];

        if (iref) {
            xImage = [UIImage imageWithCGImage:iref];
        }

        xPhoto = xImage;

    };


    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"Error fetching photo: %@",[myerror localizedDescription]);
    };


    NSURL *asseturl = [NSURL URLWithString:URLReference];

    // create library and set callbacks
    ALAssetsLibrary *al = [DetailsViewController defaultAssetsLibrary];
    [al assetForURL:asseturl 
        resultBlock:resultblock
       failureBlock:failureblock];   

    return xPhoto;

}

NOTE: This above code does run, it simply does not attach the image. 注意:上面的代码可以运行,只是不附加图像。 Also, note, I am able to successfully attach images from the gallery within my application, as long at I have set them into a UIImageView .Image already (basically, I am taking the pointer to the image from the UIImageView and passing it to the addAttachmentData method.) It is just when I attempt to iterate through Core Data and attach without first setting the image into a UIImageView that I have the trouble. 另外,请注意,只要我已经将它们设置到UIImageView .Image中,我就可以成功地将其图像附加到我的应用程序中(基本上,我是将指针从UIImageView传递到图像,并将其传递给addAttachmentData方法)。这只是当我尝试通过核心数据进行迭代并附加不首先将图像设置成UIImageView ,我有麻烦了。

Any tips would be greatly appreciated! 任何提示将非常感谢!

Thanks! 谢谢! Jason 杰森

Oh now I see it.. sry. 哦,现在我明白了。 You are using an asynchronous block to get the image from the asset library. 您正在使用异步块从资产库获取图像。 But right after starting that operation, you are returning xImage . 但是在开始该操作后,您将返回xImage But the asynchronous operation will finish later. 但是异步操作将在稍后完成。 So you are returning nil. 因此,您返回的是nil。

You need to change your architectur to smth like this: 您需要像这样更改您的架构师:

In your .h file you need two new members: 在您的.h文件中,您需要两个新成员:

NSMutableArray* mArrayForImages;
NSInteger mUnfinishedRequests;

In your .m file do smth like that: 在您的.m文件中执行以下操作:

- (void)sendReportReport
{
    // save image count
    mUnfinishedRequests = [fetchedPhotos count];

    // get fetchedPhotos
    [...]

    // first step: load images
    for (NSManagedObject *managedObject in fetchedPhotos )
    {
        [self loadImage:photo.referenceURL];    
    }
}

Change your getImage method to loadImage: 将您的getImage方法更改为loadImage:

- (void)loadImage:(NSString *)URLReference
{
    NSURL *asseturl = [NSURL URLWithString:URLReference];

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {    
        // get the image
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullScreenImage];

        if (iref) {
            [mArrayForImages addObject: [UIImage imageWithCGImage:iref]];
        } else {
            // handle error
        }

        [self performSelectorOnMainThread: @selector(imageRequestFinished)];
    };

    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"Error fetching photo: %@",[myerror localizedDescription]);

        [self performSelectorOnMainThread: @selector(imageRequestFinished)];
    };


    // create library and set callbacks
    ALAssetsLibrary *al = [DetailsViewController defaultAssetsLibrary];
    [al assetForURL:asseturl 
        resultBlock:resultblock
       failureBlock:failureblock];
}

Create a new callback method: 创建一个新的回调方法:

- (void) imageRequestFinished
{
    mUnfinishedRequests--;
    if(mUnfinishedRequests <= 0)
    {
       [self sendMail];
    }
}

And an extra method for finally sending the mail, after getting the images: 还有一种在获取图像后最终发送邮件的额外方法:

- (void) sendMail
{
    // crate mailcomposer etc
    [...]

    // attach images
    for (UIImage *photo in mArrayForImages )
    {
                NSData *imageData = UIImageJPEGRepresentation(photo, 0.5);
                [mailer addAttachmentData:imageData mimeType:@"image/jpeg" fileName:[NSString stringWithFormat:@"a.jpg"]];
    }

    // send mail
    [...]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM