Save Screenshot to Custom Photo Album - ios

I am currently in the process in creating a new app which analyses certain aspects of the user and makes the funny.
I am stuck on one part though, at the end of the app, when the user gets their results back, I want it so they can save it to a custom Album specifically for screenshots from this app.
-(IBAction)save:(id)sender {
toolBar.hidden = YES;
[self performSelector:#selector(screenPause) withObject:nil afterDelay:0.001];
}
-(void)screenPause {
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(screenshotImage, nil, nil, nil);
[self performSelector:#selector(screenPauseOne) withObject:nil afterDelay:0.001];
}
This is how I am currently capturing the screen. And as you can see, I am just saving it to the default album. How would I create a new album and then place captured images into it?
Thanks in advance,
Rafee

You need to use the AssetsLibrary framework.
Here is a tutorial that explains how to do it:
http://www.touch-code-magazine.com/ios5-saving-photos-in-custom-photo-album-category-for-download/

To my understanding what phix23 is telling you is that the code you are looking for is:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[self.library saveImage:image toAlbum:#"YourCustomAlbumName" withCompletionBlock:^(NSError *error) {
if (error!=nil)
{
NSLog(#"Big error: %#", [error description]);
}
}];
[picker dismissModalViewControllerAnimated:NO];
}
The block code starting with [self is where the magic happens.

Related

iOS Share extension cannot load panorama image

When I am sending a panorama image (made with default panorama mode of my iPhone) to my iOS Share extension, hasItemConformingToTypeIdentifier tells me that there is indeed an image sent, however loadItemForTypeIdentifier does not return anything.I don't have any completeRequestReturningItems on the whole flow which could prevent the loadItemForTypeIdentifier to proceed until the end. This works however fine with a normal image.
How come panorama images give issues ?
for (NSExtensionItem *item in self.extensionContext.inputItems)
{
for (NSItemProvider *itemProvider in item.attachments)
{
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage])
{
NSLog(#"Found item:%#",item); --> Is displayed
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error)
{
NSLog(#"Item delivered"); --> Is never displayed for panorama pictures
if(image) {
selectedImage=image;
mediaType=1;
NSLog(#"Image found !!");
imageFound = YES;
}
}];
break;
}
}
}

Swift - not working correctly IOS 9.2

I have added a table view, and I am display image in the cells. I have also added this code:
So that the cells resize depending on the image.
When I launch my app though, I get this : [![enter image description here][1]][1]
And the images do not load untill I start scrolling...If I scroll down half the page then go back to the top, I get this: Which is correct
[![enter image description here][2]][2]
Any ideas? I have researched on google and tried the odd solution for the older versions of Xcode, But nothing seems to work!
Here is the rest of my code from the TableViewController:
Image isn't loaded correctly in cellForRowAtIndexPath delegate method, you're (probably) downloading the image in the background, so cellForRowAtIndexPath is returned before image is ready.
Downloaded image is probably cached somewhere so next time it's loaded properly.
post.downloadImage() better have a callback closure to be called when image was downloaded, to assign the downloaded image into the proper cell.
Keep in mind that user may scroll this cell out of the screen before image is loaded, so you better use a unique id to abort downloaded image assignment if cell has already changed.
Here's an example for a method that downloads an image in the background, then assigns it to the cell -
+ (void)loadImage:(NSString *)imageUrl onComplete:(void(^)(UIImage *image, BOOL loaded, NSString *callIdentifier))callback callIdentifier:(NSString *)callIdentifier {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul), ^{
[self downloadPicture:url onComplete:^(UIImage *image, BOOL loaded) {
dispatch_sync(dispatch_get_main_queue(), ^{
callback(image, loaded, callIdentifier);
});
}];
});
callback([UIImage imageNamed:#"placeholder"], NO, callIdentifier);
}
+ (void)downloadPicture:(NSString *)url saveTo:(NSString *)filePath onComplete:(void (^)(UIImage *image, BOOL loaded))onComplete {
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url] options:NSDataReadingMappedAlways error:&error];
if (!error) {
UIImage *image = [UIImage imageWithData:data scale:GTUserPictureScale];
if (onComplete)
onComplete(image, YES);
} else {
NSLog(#"Error loading user picture: %#", [error description]);
if (onComplete)
onComplete([UIImage imageNamed:#"missing"], NO);
}
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
__weak MyClass *wself = self;
self.imageUrl = #"http://...";
[self loadImage:self.imageUrl onComplete:^(UIImage *image, BOOL loaded, NSString *callIdentifier) {
#synchronized(wself) {
if ([callIdentifier isEqualToString:wself.imageUrl]) {
if (loaded) {
wself.image = image;
}
} else
NSLog(#"Expired load image request for id %#", callIdentifier);
}
} callIdentifier:self.imageUrl];
// ...
}

ALAssetsLibraryWriteVideoCompletionBlock return undefined values

ALAssetsLibraryWriteVideoCompletionBlock is returning undefined values. If assetURL is equal to nil, then error ought to be not equal to nil, that is, return to me some error description.
See apple documentation at here.
When I record small video, ALAssetsLibraryWriteVideoCompletionBlock return a good value of assetURL, but when I record long video 3 or 4 Gb, assetURL return nil and error return nil. Video recorded is in tmp file because I can see this video in temporally folder in my app. It seems like IOS framework try to do a copy of this temporally file to photo album and iPhone don't have enough memory to copy this temp file to photo album and return a path of this file (assetURL).
Is this a bug in iOS framework? If so, is there a way to fix it?
UPDATE:
My files is less than 4GB. Thanks
UPDATE with source code:
-(void)recorder:(AVCamRecorder *)recorder recordingDidFinishToOutputFileURL:(NSURL *)outputFileURL error:(NSError *)error
{
if ([[self recorder] recordsAudio] && ![[self recorder] recordsVideo]) {
// If the file was created on a device that doesn't support video recording, it can't be saved to the assets
// library. Instead, save it in the app's Documents directory, whence it can be copied from the device via
// iTunes file sharing.
[self copyFileToDocuments:outputFileURL];
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
[[UIApplication sharedApplication] endBackgroundTask:[self backgroundRecordingID]];
}
if ([[self delegate] respondsToSelector:#selector(captureManagerRecordingFinished:)]) {
[[self delegate] captureManagerRecordingFinished:self];
}
}
else {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
if ([[self delegate] respondsToSelector:#selector(captureManager:didFailWithError:)]) {
[[self delegate] captureManager:self didFailWithError:error];
}
}
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
[[UIApplication sharedApplication] endBackgroundTask:[self backgroundRecordingID]];
}
if (assetURL!=nil)
{
if ([[self delegate] respondsToSelector:#selector(captureManagerRecordingFinished:)]) {
[[self delegate] captureManagerRecordingFinished:self];
}
}
else
{
NSLog(#"Video is not saved");
NSString *alertMsg = [NSString stringWithFormat:#"Impossible to copy video to photo album"];
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"info"];
[alert setMessage:alertMsg];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Accept"];
[alert show];
}
}];
}
}
I have almost the same issue: just that I try to save photos, not movies; but still assetURL is NULL. Here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
[library writeImageToSavedPhotosAlbum:(__bridge CGImageRef)([info objectForKey:UIImagePickerControllerOriginalImage])
orientation:ALAssetOrientationUp completionBlock:^(NSURL *assetURL, NSError *error) {
if(error == nil) {
_myImageUrl = [NSString stringWithFormat:#"%#",assetURL];
NSLog(#"%#",assetURL);
} else NSLog(#"%#",error);
}];
[picker dismissViewControllerAnimated:YES completion:nil];
}
So, I guess this issue is not related to the size of the file..
I do different tests and I can save videos with more than 2Gb. In this case I delete a lot of files in my iPhone until I had 7Gb, then I saved a video with 3.2Gb (3.8Gb free) and store in photo gallery. Then I saved other video with 2Gb and it didn't save in photo gallery. What does it means?. Well, when you are saving a temp video, then you need at least the same or more free space than the video that you are trying to copy to photo gallery.
The problem here is that IOS7 framework doesn't return any error with his function writeVideoAtPathToSavedPhotosAlbum, in this case it have to return ALAssetsLibraryWriteDiskSpaceError = -3305. Maybe in previous version of IOS framework it works...but in IOS7 not.
By the way, I open a ticket in apple bug reporter. If they tell me something different I will post it.
Thanks for all guys.
ADD: FYI, I save a video file with more than 4Gb (4.6Gb) in IOS 7.0.3

How capture photo then iOS-app is minimized?

How take picture from camera when iOS-app is minimized?
(i.e. after applicationDidEnterBackground: / applicationWillResignActive: )
AppDelegate.m: (thank you link)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//To make the code block asynchronous
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//### background task starts
NSLog(#"Running in the background\n");
while(TRUE)
{
printf("Called"); //////Work fine
[self.window.rootViewController captureNow]; /////Capture picture!
[NSThread sleepForTimeInterval: 10.0]; //wait for 10 sec
}
});
return YES;
}
OurViewController.m: (thank you link)
-(IBAction)captureNow {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in _stillImageOutput.connections)
{
for (AVCaptureInputPort *port in [connection inputPorts])
{
if ([[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
break;
}
}
if (videoConnection)
{
break;
}
}
NSLog(#"about to request a capture from: %#", _stillImageOutput);
[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (error)
{
NSLog(#"ERROR = %#", error); ///// Error!
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; ////SIGABRT, cause imageSampleBuffer is nil
UIImage *image = [[UIImage alloc] initWithData:imageData];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
[image release];
}];
}
This code works fine, when application is active. But take error (SIGABRT), when app is minimized.
Maybe are there other libraries can afford to do it?
For privacy reasons, you're not allowed to access the camera when your app is in the background.
Why?
Well, I'm glad you asked that. Story time!
Bob is a person who works at the NSA, developing super-secret monkey controlling sharks. Why? He can't say.
Bob one day downloaded an app onto his iPhone, called John's Secret Stealer. Bob doesn't read app titles.
Since Bob is a very forgetful person, he one day forgot to leave his phone in the lockers outside of work. While standing over the super-secret shark recipe, he felt his phone in his pocket, and pulled it out. It had buzzed because he just got a text.
At that moment, John's Secret Stealer took a picture using Bob's phone's rear camera, sent it off to John's servers, and Bob never knew.
The next day, the entire world knew about the secret project to control sharks.
That's an extreme example, but it's the principal of the rule. Apple's policy is that the user is always in control - to avoid situations like Bob's.

How do I display the images in a custom album in my iOS App

I have created a custom album with using the below code
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
<--other code stuffs here-->
<--selectedImage is the UIImage from Camera or from gallery-->
[self.library saveImage:selectedImage toAlbum:#"My Album" withCompletionBlock:^(NSError *error)
{
if (error!=nil)
{
NSLog(#"Big error: %#", [error description]);
}
}];
<--other code stuffs here-->
}
Now I want to display these saved images in my application.
How do I access these images, and create a gallery in my APP.
Thanks,
Sujith
The method you want is the ALAssetsLibrary method addAssetsGroupAlbumWithName:resultBlock:failureBlock: which is detailed in the docs here: http://developer.apple.com/library/ios/#documentation/AssetsLibrary/Reference/ALAssetsLibrary_Class/Reference/Reference.html#//apple_ref/occ/cl/ALAssetsLibrary
It was introduced in iOS 5 and has not since been deprecated, so I'm not quite sure what the issue is if it's not working for you. You may have to update or repost the question if you are having trouble with it.

Resources