iOS. Приемы программирования — страница 88 из 124

Постановка задачи

Требуется сохранить в библиотеке фотографий видеоролик, доступный по URL, например ролик из пакета вашего приложения.

Решение

Воспользуйтесь методом экземпляра writeVideoAtPathToSavedPhotosAlbum: completionBlock:, относящимся к классу ALAssetsLibrary:


#import «AppDelegate.h»

#import 


@interface AppDelegate ()

@property (nonatomic, strong) ALAssetsLibrary *assetsLibrary;

@end


@implementation AppDelegate

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


self.assetsLibrary = [[ALAssetsLibrary alloc] init];


NSURL *videoURL = [[NSBundle mainBundle] URLForResource:@"MyVideo"

withExtension:@"MOV"];


if (videoURL!= nil){

[self.assetsLibrary

writeVideoAtPathToSavedPhotosAlbum: videoURL

completionBlock: ^(NSURL *assetURL, NSError *error) {


if (error == nil){

NSLog(@"no errors happened");

} else {

NSLog(@"Error happened while saving the video.");

NSLog(@"The error is = %@", error);

}


}];

} else {

NSLog(@"Could not find the video in the app bundle.");

}


return YES;

}

Обсуждение

Фреймворк Assets Library — удобный посредник между разработчиком и библиотекой фотографий. Как будет указано в разделе 13.6, в iOS SDK вам предоставляются встроенные компоненты графического пользовательского интерфейса, которыми можно пользоваться для доступа к содержимому библиотеки фотографий. Тем не менее иногда может потребоваться и непосредственный доступ к этому содержимому. В таких случаях следует пользоваться фреймворком библиотеки ресурсов (Assets Library).

Выделив и инициализировав объект Assets Library типа ALAssetsLibrary, можно пользоваться методом экземпляра writeVideoAtPathToSavedPhotosAlbum: completionBlock:, относящимся к данному объекту, для записи видео с URL в библиотеку фотографий. Все, что от вас требуется, — предоставить URL видеоролика в форме NSURL, а также блоковый объект, чей код будет вызываться после сохранения видео. Этот блоковый объект должен принимать два параметра типов NSURL и NSError.

Если параметр error имеет значение nil, процесс сохранения прошел нормально и поводов для беспокойства нет. Одна из типичных ошибок, которую iOS может вам вернуть в такой ситуации, примерно такова:


Error Domain=ALAssetsLibraryErrorDomain Code=-3302 «Invalid data»

UserInfo=0x79 23590 {NSLocalizedFailureReason=

There was a problem writing this asset because

the data is invalid and cannot be viewed or played.,

NSLocalizedRecoverySuggestion=Try with different data,

NSLocalizedDescription=Invalid data}


Такое сообщение об ошибке вы можете получить и в случае, если попытаетесь передать URL (уникальный идентификатор ресурса), не относящийся к пакету вашего приложения.

Первый параметр, передаваемый блоковому объекту, который, в свою очередь, предоставляется методу writeVideoAtPathToSavedPhotosAlbum: completionBlock:, будет указывать URL видео, сохраненного в библиотеке ресурсов. URL такого рода может иметь следующий вид:


assets-library://asset/asset.MOV?id=F9B5F733-487C-

4418-8C8D-46ABC9FEE23B&ext=MOV


Если ваша программа впервые пытается обратиться к библиотеке фотографий на пользовательском устройстве, то iOS спросит у пользователя, разрешена такая операция или нет. Если пользователь даст разрешение, то вызов метода writeVideoAtPathToSavedPhotosAlbum: completionBlock: будет успешным. Если же разрешение получено не будет, то объект ошибки внутри блока завершения будет валидным объектом ошибки, который вы можете проверить и над которым можете выполнять действия. Если ранее пользователь не разрешил вашему приложению доступ к библиотеке фотографий, то вы не сможете изменить это решение программно. Лишь когда сам пользователь решит предоставить вам доступ к библиотеке фотографий, он изменит соответствующие настройки в разделах Settings (Настройки) и Privacy (Конфиденциальность).

В разделе 13.7 будет рассказано, как использовать такой URL при загрузке в память данных для видеофайла.

13.6. Получение фото и видео из библиотеки фотографий

Постановка задачи

Необходимо предоставить пользователю возможность выбирать фото или видео из своей библиотеки фотографий и использовать их в приложении.

Решение

При работе с объектом UIImagePickerController используйте UIImagePickerControllerSourceTypePhotoLibrary в качестве типа источника и значение kUTTypeImage или kUTTypeMovie для типа медийной информации:


— (BOOL) isPhotoLibraryAvailable{


return [UIImagePickerController isSourceTypeAvailable:

UIImagePickerControllerSourceTypePhotoLibrary];


}


— (BOOL) canUserPickVideosFromPhotoLibrary{


return [self

cameraSupportsMedia:(__bridge NSString *)kUTTypeMovie

sourceType: UIImagePickerControllerSourceTypePhotoLibrary];


}


— (BOOL) canUserPickPhotosFromPhotoLibrary{


return [self

cameraSupportsMedia:(__bridge NSString *)kUTTypeImage

sourceType: UIImagePickerControllerSourceTypePhotoLibrary];


}


— (void)viewDidAppear:(BOOL)animated{

[super viewDidAppear: animated];


static BOOL beenHereBefore = NO;


if (beenHereBefore){

/* Отображаем элемент для выбора даты только после того, как вызывается

метод viewDidAppear:, что происходит при каждом отображении вида

нашего контроллера вида */

return;

} else {

beenHereBefore = YES;

}


if ([self isPhotoLibraryAvailable]){


UIImagePickerController *controller =

[[UIImagePickerController alloc] init];


controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

NSMutableArray *mediaTypes = [[NSMutableArray alloc] init];


if ([self canUserPickPhotosFromPhotoLibrary]){

[mediaTypes addObject:(__bridge NSString *)kUTTypeImage];

}


if ([self canUserPickVideosFromPhotoLibrary]){

[mediaTypes addObject:(__bridge NSString *)kUTTypeMovie];

}


controller.mediaTypes = mediaTypes;

controller.delegate = self;

[self.navigationController presentModalViewController: controller

animated: YES];

}

}


О том, как реализовать метод cameraSupportsMedia: sourceType:, который используется в этом примере, рассказано в разделе 13.1.

Обсуждение

Чтобы пользователь мог выбирать фотоснимки или видеоролики из своей библиотеки фотографий, необходимо установить свойство sourceType экземпляра UIImagePickerController в значение UIImagePickerControllerSourceTypePhotoLibrary и только потом открывать перед пользователем инструмент для выбора изображений. Кроме того, если вы хотите отфильтровать определенные фотографии или видеоролики из общего числа элементов, представленных пользователю в инструменте для выбора изображений, исключите значение kUTTypeMovie или kUTTypeImage соответственно из списка типов медийной информации, отображаемой в инструменте для выбора изображений (это делается в свойстве mediaTypes).

Учитывайте, что, если установить значение свойства mediaTypes контроллера для выбора изображений в nil, получится пустой массив, который спровоцирует ошибки времени исполнения.

После того как пользователь выберет желаемое изображение, вы будете получать обычные сообщения делегата, соответствующие протоколу UIImagePickerControllerDelegate. Подробнее о реализации методов, определяемых в этом протоколе для обработки изображений, рассказано в разделе 13.2.

См. также

Раздел 13.7.

13.7. Получение ресурсов из библиотеки ресурсов