【问题标题】:MFMailComposeViewController: Attaching Images from Photo GalleryMFMailComposeViewController:附加照片库中的图像
【发布时间】:2012-03-06 16:10:26
【问题描述】:

我在将照片库中的图片附加到电子邮件时遇到了一些问题。

基本上,我的应用程序的一项功能允许用户拍照。当他们拍摄照片时,我会在 Core Data 中记录对图像的 URL 引用。我知道您必须通过ALAssetRepresentation 才能获得图像。当用户想要查看他们拍摄的图像时,我在我的应用程序中启动并运行了它。

我现在正尝试允许用户将所有为活动拍摄的照片附加到电子邮件中。在执行此操作时,我遍历存储 URL 引用的核心数据实体,调用从 ALAssetsLibrary 返回 UIImage 的方法,然后使用 NSData/UIImageJPEGRepresentationMFMailComposeViewController/@ 附加它987654327@ 方法。

问题是:当邮件呈现给用户时,有代表图片的蓝色小方块,图片没有附上。

代码如下:

- (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];

    }

}

以及返回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;

}

注意:上面的代码确实可以运行,它只是不附加图像。另外,请注意,只要我已经将它们设置为UIImageView.Image,我就能够成功地在我的应用程序中附加来自图库的图像(基本上,我正在从UIImageView 中获取指向图像的指针和将它传递给addAttachmentData 方法。)只是当我尝试遍历核心数据并附加而没有先将图像设置为UIImageView 时,我遇到了麻烦。

任何提示将不胜感激!

谢谢! 杰森

【问题讨论】:

  • 您是否在将图像添加为附件之前打印了图像的内容? (CFShow([self getImage:photo.referenceURL]);) 也许现在为零?
  • 嗨 Jaydee,我猜你是对的。很可能为零。但是,我该怎么办?我是否以错误的方式处理这个问题,但是创建了一个返回 UIImage 的方法?我应该做一些不同的事情来遍历我对照片库图像的 URL 引用列表吗?
  • 上去找错误。如果图像为零,那么您的参考 URL 显然是错误的。因此,请检查 URL 是如何创建的..
  • 参考网址没有错。正如我在原始帖子中所述,我能够在我的应用程序的另一个视图中成功地从参考 URL 呈现图像。正如您所猜测的那样,图像为零,但我不明白为什么。我认为这与通过返回方法返回 UIImage 有关。如果您了解 ALAssetsLibraryAssetForURLResultBlock,如果您查看 getImage 方法并让我知道您是否看到任何会导致图像返回为 nil 的内容,我将不胜感激。我确实看到了 cfshow 的图像,但它没有返回。

标签: iphone ios ios5 alassetslibrary messageui


【解决方案1】:

哦,现在我明白了.. sry。您正在使用异步块从资产库中获取图像。但在开始该操作后,您将返回xImage。但异步操作将在稍后完成。所以你返回 nil。

你需要像这样改变你的架构师:

在您的 .h 文件中,您需要两个新成员:

NSMutableArray* mArrayForImages;
NSInteger mUnfinishedRequests;

在你的 .m 文件中这样做:

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

    // get fetchedPhotos
    [...]

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

将您的 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];
}

创建一个新的回调方法:

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

还有一个额外的方法,在获取图片后最终发送邮件:

- (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
    [...]
}

【讨论】:

  • 这是伟大的杰迪!!!让我试一试,然后我会将其标记为已回答。谢谢你的帮助。非常感谢您的宝贵时间。
  • 我真的不知道出了什么问题,但由于某种原因,数组没有添加任何对象。 Core Data 中记录了两个图像,CFImageRef 被调用了两次,当我查看 CFShow(iref) 时,我得到 ,但是当我查看 CFShow(mArrayForImages) 时,我得到 (null)。您的架构看起来非常合理,但由于某种原因,该对象没有被添加到数组中。它实际上类似于调用我的方法时发生的情况。
  • 我刚刚创建了另一个全新的视图,其中包含两个 UIImageView 控件和一个 UIButton,并且能够在 UIImageView 中成功显示来自 Core Data URL References 的图像。我真的很难过。
  • 你必须先初始化数组 :) [NSMutableArray alloc] init] 当然在你的dealloc 中释放它。
  • 嘿,我只是想说谢谢你帮助我。我很感激你的时间。你提出的方法是完美的。再次感谢杰迪!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
相关资源
最近更新 更多