Показаны сообщения с ярлыком UIImagePickerController. Показать все сообщения
Показаны сообщения с ярлыком UIImagePickerController. Показать все сообщения

среда, 8 января 2014 г.

Работа с фото видео камерой в IOS IPhone используя UIImagePickerController

У многих разработчиков мобильных приложений возникает вопрос о реализации работы с камерой. Я уже описывал этот процесс для Android теперь хочу сделать краткое описание для IOS на IPhone. Речь пойдёт именно об использовании UIImagePickerController как самого простого способа. Описывать подробно создание проекта и установки кнопки в storyboard я не буду это вы можете посмотреть в моей прошлой статье.

Предпочитается, что у вас уже есть кнопка по которой мы хотим вызвать камеру и получить например фото после того как вы нажмете фотографировать. Поэтому я опишу лишь методы которые необходимо реализовать в класе вашего ViewCotroller-а.
Итак вызов камеры:
-(IBAction) makePhoto:(id)sender{
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]){
// Создание image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Устанавливаем сорс для камеры
imagePicker.sourceType =  UIImagePickerControllerSourceTypeCamera;
imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
// Текущий Delegate
imagePicker.delegate = self;
imagePicker.mediaTypes = [UIImagePickerController  availableMediaTypesForSourceType:imagePicker.sourceType];
// Показываем image picker
[self presentModalViewController:imagePicker animated:YES];
}else{
NSLog(@»Ваше устройство не поддерживает эту функцию»);
}
}
В этом методе мы настраиваем UIImagePickerController и показываем пользователю активность в которой он работает, и соответственно можно сделать фото. Поскольку делегатом является self,  то есть реализация методов обработки полученных результатов должна быть в этом же классе.
Подвяжите метод типа IBAction к кнопке на Tuch up inside и запустите проект. Конечноже проверять необходимо на реальном устройстве, так как на эмуляторе камеры нет и в системный лог вы получите сообщение «Ваше устройство не поддерживает эту функцию». так как в строке
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]){
мы проверяем наличие камеры на устройстве. Итак если вы запустите проект на реальном устроействе и нажмете на свою кнопку то увидите, что запустилась активность камеры, теперь можно сделать фото. Но после нажатия кнопки Use ничего не произойдет так как нам нужно реализовать ещё метод - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info поскльку делегатом для UIImagePickerController является данный класс в котором он вызван,
Итак код метода:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//определить медиа тип файла
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ( [ mediaType isEqualToString:@"public.image" ]) { //если файл – изображение
// Берем изображение из информации словаря
UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
//получить путь к файлу
NSURL* imagePath = (NSURL *)[info valueForKey:UIImagePickerControllerReferenceURL];
NSString* chosed_imagePath = [imagePath path];
//формируем file-data изображения
NSData* imageData = UIImageJPEGRepresentation(image, 1.0);
}else if ( [ mediaType isEqualToString:@"public.movie" ]){ // пользователь снял видео
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
}
}
Теперь подробнее. Как видно из данного примера мы можем получить 2 типа контента с камеры: фото и видео. У данных о фотографии мы можем получить путь, url и NSData то есть само байтовое представление файла, и  что немало важно NSData хранится в памяти и если вам не нужны эти данные лучше не хнатить их в ОЗУ а пользоваться файлом на мобильном устройстве . Поэтому как дальше работать с этими данными вам решать) У видео файла также можно получить путь и NSData но в отличии от фото оно уже в медиа-галерее вашего устройства. И так опишу ещъ один метод для сохранения изображения в медиа галерею для дальнейшей работы с ним.
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
Как вы видите в качетсве входного параметра в этом методе используется image объект типа UIImage полученный нами из камеры. Еесли вам это нужно используйте это вот так:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//определить медиа тип файла
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ( [ mediaType isEqualToString:@"public.image" ]) { //если файл – изображение
// Берем изображение из информации словаря
UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}else if ( [ mediaType isEqualToString:@"public.movie" ]){ // пользователь снял видео
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
}
}
Конечно возможно вам понадобится обработчик didFinishSavingWithError – это метод который выполнится после сохранения рисунка и может содержать ошибку, о которой нужно сообщить пользователю
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo
{
// проверка на ошибки
if (error != NULL) {
// показать ошибку…
UIAlertView* minhaCritica = [UIAlertView new];
minhaCritica.title = @»Ошибка»;
[minhaCritica addButtonWithTitle:@"Ок"];
minhaCritica.message = @»Фото не сохранилось»;
minhaCritica.delegate = self;
[minhaCritica show];
[minhaCritica release];
//это обычный алерт с кнопкной ОК и сообщением
} else  // ошибок нет
{
// показать сообщение о том что картинка сохранена
UIAlertView* minhaCritica = [UIAlertView new];
minhaCritica.title = @»Успешно»;
[minhaCritica addButtonWithTitle:@"Ок"];
minhaCritica.message = @»Фото  сохранилось»;
minhaCritica.delegate = self;
[minhaCritica show];
[minhaCritica release];
}
}
Как мы видим в обработчике идет проверка на ошибку и два варианта или успешно или неудачно тогда покажем alert с тем или иным тектом. Теперь можно запустить проект и проверить как работает получение фото с камеры и сохраненеи в галерею.

Полезные методы и функции для IOS разработчиков. Часть 2

В прошлой части полезных методов и функций я описал не все интересные примеры потому, что их очень много и теперь хочу продолжить эту тематику. Так как возможно это полезно вам и мне не даст забыть как это делается :)
Начать хотелось бы с полезного метода хранения некоторых пользовательских настроек в памяти мобильного устройства по средствам NSUserDefaults. Это некий класс с примитивными методами помогающими временно(на момент существования вашего приложения в пределах одной версии) хранить фактически любые данные. Начиная от просто строк до байтовых данных NSData. И так рассмотрим методы записи данных:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"Строка любого содержания" forKey:@"some_str"];
В первой строке мы создаём объект класса NSUserDefaults что быработать с его методами. Во второй строке мы присваиваем значение ключу some_str в виде строки с произвольным содержимым. Теперь эта строка будет хранится пока мы не удалим приложение или не обновим его до следующей версии.  Как же теперь достать эти данные при необходимости? На самом деле очень просто:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *str = [userDefaults objectForKey:@"some_str"];
Заведома зная что у нас по этому ключу лежит строка я создал объект имено NSString. Хотя если вы например укажете там Int среда Xcode не выдаст вам ошибки так как объект содержащийся в userDefaults так сказать не индексируется. Но при использовании этого метода в период работы приложения будет ошибка и XCode напишет вам её в консоль. Поэтому надо быть поаккуратнее с подобыми операциями.
Для очистки значения по ключу достаточно присвоить ключу nil подобно тому как мы дели присвоение строки в первом листинге кода.
Ещё один не маловажный момент который может пригодится, а именно знать как выбирать между двумя разными stroyboard когда это необходимо.
Но делать такую проверку и выбор stroyboard необходимо в методе – (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions класса AppDelegate.m вашего приложения, Поскольку выбрать его можно будет только до того как он станет для приложения по умолчанию, на лету это сделать нельзя. Допустим у вас уже есть stroyboard созданный XCode при создании нового приложения и вам необходимо добавить ещё один для запуска допустим на мобильных устройствах типа IPhone но с рейтина дисплеем. Создайте файл stroyboard и назовите его к примеру Rstoryboard.
И так открываем выше упомянутый метод и пишем слдеующий код:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
UIStoryboard *storyBoard;
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
//проверим высоту экрана телефона
if(result.height == 1136){ //это нам подходит для определения рейтина дисплея
storyBoard = [UIStoryboard storyboardWithName:@"Rstoryboard" bundle:nil];//устанавливаем нужный нам Rstoryboard
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
}
Далее рассмотрим на примере код который позволит из вашего приложения открыть itunes со  страницей вашего приложения например для оценки или написания отзыва.
NSURL *appStoreURL = [NSURL URLWithString:@"ссылка на приложение"];
[[UIApplication sharedApplication] openURL:appStoreURL];
Фактически этот метод откроет safari но сам safari перенаправит пользователя на itunes. Ссылку на приложение легко сформировать нажав на стрелку возле Downlowd  на странице вашего приложения в Itunes, и выбрав copy link.

Пока это всё, что я хотел рассказать на данный момент, надеюсь наберётся материалов на третью часть.