MFMailComposeViewController: прикрепление изображений из фотогалереи
У меня проблемы с прикреплением изображений из фотогалереи к электронному письму.
В принципе, одна из функций моего приложения позволяет пользователю делать фотографии. Когда они делают снимок, я записываю ссылку URL на изображение в Core Data. Я понимаю, что вы должны пройти через ALAssetRepresentation
чтобы добраться до изображения. У меня есть это и работает в моем приложении, когда пользователь хочет просмотреть изображение, которое он сделал.
Сейчас я пытаюсь разрешить пользователю прикрепить все фотографии, сделанные для мероприятия, к электронному письму. При этом я перебираю сущность Core Data, в которой хранятся URL-ссылки, и вызываю метод, который возвращает UIImage
от ALAssetsLibrary
а затем прикрепляет его с помощью NSData
/UIImageJPEGRepresentation
а также MFMailComposeViewController
/addAttachmentData
методы.
Проблема в том, что: когда письмо представляется пользователю, появляются маленькие синие квадраты, представляющие изображения, и изображение не прикреплено.
Вот код:
- (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
.Изображение уже (в основном, я беру указатель на изображение из UIImageView
и передать его addAttachmentData
метод.) Это просто, когда я пытаюсь перебрать Core Data и присоединить без предварительной установки изображения в UIImageView
что у меня проблема.
Любые советы будут с благодарностью!
Спасибо! Джейсон
1 ответ
Ох, теперь я вижу это.. sry. Вы используете асинхронный блок для получения изображения из библиотеки ресурсов. Но сразу после запуска этой операции вы возвращаетесь xImage
, Но асинхронная операция закончится позже. Итак, вы возвращаете ноль.
Вам нужно изменить архитектуру на что-то вроде этого:
В вашем.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
[...]
}