PHPhotoLibrary save a gif data - objective-c

I can't find a similar method to ALAssetsLibrary->writeImageDataToSavedPhotosAlbum in the new PHPhotoLibrary since ALAssetsLibrary deprecated in iOS 9 I can't save GIF probably I'm using this code
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageWithData:gifdata]];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
}
else
{
NSLog(#"%#", error);
}
}];

I used NSData to save the gif image, ALAssetsLibrary method UIImageWriteToSavedPhotosAlbum deprecated after iOS8,The api says we can use
PHAssetCreationRequestmethod [[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto data:data options:options]; to save this gif image data, so you can use url request to save gifs as well
codes are follows:
NSString *path = [[NSBundle mainBundle] pathForResource:#"1" ofType:#"gif"];
NSData *data = [NSData dataWithContentsOfFile:path];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
[[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto data:data options:options];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
NSLog(#":%d",success);
}];

I've save gif file successfully to Photos Gallery by using Photos Framework
PHPhotoLibrary.shared().performChanges ({
let url = URL(fileURLWithPath: "your file path")
PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: url)
}) { saved, error in
if saved {
print("Your image was successfully saved")
}
}
Hope this help!

I solved my issue by creating temp file and using :
creationRequestForAssetFromImageAtFileURL

Related

Downloading From Parse on Apple TV

The bounty expires in 3 days. Answers to this question are eligible for a +500 reputation bounty.
user717452 wants to draw more attention to this question.
I have a parse server set up, and as part of it, small PDFs (425KB) are stored on it. I need my Apple TV to be able to display these, but since they change often, it has to come from Parse server, and not just the main bundle where I update it with each update of the app. The issue I'm running into is the lack of an NSDocumentsDirectory on the Apple TV. How do y'all handle this? I've been using the Cache directory, but it seems to only work half the time with the code I am currently using. If I run it at launch from AppDelegate, by the time the PDF is needed, it may not be there, and if I have it set to run this code right when I need it, there is a delay, and sometimes, it simply doesn't show up. Would using NSTemporaryDirectory() be better? UPDATE, no, it doesn't. Works fine on simulator, on Apple TV, have to run the code two times to get it to both download, and draw the PDF
-(void)sermonTime {
//Check if PFFile exists, if so, display PDF, if not, blank time.
if ([self.entry[#"SermonPresIncluded"] isEqualToString:#"NO"]) {
[self blankTime];
}
else {
NSLog(#"SermonTime");
PFFileObject *thumbnail = self.entry[#"SermonPDF"];
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [[documentsDirectory stringByAppendingPathComponent:[self.entry valueForKey:#"DateOfService"]] stringByAppendingString:#".pdf"];
[imageData writeToFile:pdfPath atomically:YES];
NSURL *url = [NSURL fileURLWithPath:pdfPath];
self.view.backgroundColor = [UIColor blackColor];
self.arrayOfVerses = #[#"allverses"];
CGPDFDocumentRef pdfDocument = [self openPDF:url];
[self drawDocument:pdfDocument];
}];
}
}
-(void)sermonTime {
// Check if PFFile exists, if so, display PDF, if not, blank time.
if ([self.entry[#"SermonPresIncluded"] isEqualToString:#"NO"]) {
[self blankTime];
}
else {
NSLog(#"SermonTime");
PFFileObject *thumbnail = self.entry[#"SermonPDF"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [[documentsDirectory stringByAppendingPathComponent:[self.entry valueForKey:#"DateOfService"]] stringByAppendingString:#".pdf"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:pdfPath]) {
// Use cached copy of PDF
NSURL *url = [NSURL fileURLWithPath:pdfPath];
self.view.backgroundColor = [UIColor blackColor];
self.arrayOfVerses = #[#"allverses"];
CGPDFDocumentRef pdfDocument = [self openPDF:url];
[self drawDocument:pdfDocument];
} else {
// Download and save the PDF
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (error) {
// Handle the error
NSLog(#"Error downloading PDF: %#", error);
[self blankTime];
} else {
[imageData writeToFile:pdfPath atomically:YES];
// Use completion block to signal that the PDF is ready to display
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *url = [NSURL fileURLWithPath:pdfPath];
self.view.backgroundColor = [UIColor blackColor];
self.arrayOfVerses = #[#"allverses"];
CGPDFDocumentRef pdfDocument = [self openPDF:url];
[self drawDocument:pdfDocument];
});
}
}];
}
}
}
Made some changes to the code.
It will first check if the PDF exists cache, it will use the PDF if it exists in cache and will only proceed download if it does not exists. Then, to make sure that PDF is downloaded and saved successfully you can use a completion block. With completion block, it will only proceed to draw it when the block is called to avoid the PDF does't show up.

Play Last recording in Watchkit OS 2

i use the sample codes from apple for recording and playing the last recording
but i can't play the last recording
here are the codes
- (IBAction)playLastRecording {
// Present the media player controller for the last recorded URL.
NSDictionary *options = #{
WKMediaPlayerControllerOptionsAutoplayKey : #YES
};
[self presentMediaPlayerControllerWithURL:self.lastRecordingURL options:options completion:^(BOOL didPlayToEnd, NSTimeInterval endTime, NSError * __nullable error) {
if (!didPlayToEnd) {
NSLog(#"The player did not play all the way to the end. The player only played until time - %.2f.", endTime);
}
if (error) {
NSLog(#"There was an error with playback: %#.", error);
}
}];
}
and here is the error
i think we need to use the NSbundle and nsurl connection but how
to use for self.lastRecordingURL
please writing the correct codes for this problems
Optional(Error Domain=com.apple.watchkit.errors Code=4 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (1), NSUnderlyingError=0x17d9bf50 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}, NSLocalizedDescription=The operation could not be completed})
I had this problem. Make sure that the audio data is saved to the Apps Group correctly with the correct extension of the file.
If you are trying to record the audio file use the following codes.
- (void)startRecording
{
// Creating a path for saving the recorded audio file.
// We have to write the files to the shared group folder, as this is the only place both the app and extension can see.
NSURL *container = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:APP_GROUP_IDENTIFIER];
NSURL *outputURL = [container URLByAppendingPathComponent:#"AudioFile.m4a"];
// Setting the recorder options.
NSDictionary *dictMaxAudioRec = #{#"WKAudioRecorderControllerOptionsMaximumDurationKey":MAX_REC_DURATION};
// Presenting the default audio recorder.
[self presentAudioRecorderControllerWithOutputURL:outputURL preset:WKAudioRecorderPresetWideBandSpeech options:dictMaxAudioRec completion:^(BOOL didSave, NSError * error) {
if(didSave)
{
// Successfully saved the file.
NSURL *extensionDirectory = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
NSUInteger timeAtRecording = (NSUInteger)[NSDate timeIntervalSinceReferenceDate];
NSString *dirName = [NSString stringWithFormat:#"AudioFile%d/",timeAtRecording];
NSURL *outputExtensionURL = [extensionDirectory URLByAppendingPathComponent:dirName];
// Move the file to new directory.
NSError *moveError;
BOOL success = [[NSFileManager defaultManager] moveItemAtURL:outputURL toURL:outputExtensionURL error:&moveError];
if (!success) {
NSLog(#"Failed to move the outputURL to the extension's documents direcotry: %#", moveError);
}
else {
NSData *audioData = [NSData dataWithContentsOfURL:outputExtensionURL];
NSLog(#"Actual Audio Data length: %lu", (unsigned long)audioData.length);
if(audioData.length)
{
// We have a valid audio data,do what ever you want to do with this data
}
}
}
else
{
// Something went wrong.
NSLog(#"%s - %#",__PRETTY_FUNCTION__,error);
}
}];
}
Or if you are trying to play a video that you have downloaded from other source or passed from the paired phone, write the audio data first to the App Groups with file extension. The following codes may help you for that.
- (void)writeAudioToAppGroupsWithData:(NSData *)audioData
{
// Writing the audio data to the App Groups
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:APP_GROUP_IDENTIFIER];
containerURL = [containerURL URLByAppendingPathComponent:[NSString stringWithFormat:DIRECTORY_PATH]];
[audioData writeToURL:containerURL atomically:YES];
}
In this case make sure that your DIRECTORY_PATH is Library/Caches/filename.extension.
Eg: Library/Caches/Audio.mp3
For playing the saved audio use the following codes.
- (void)playAudio
{
// Playing the audio from the url using the default controller
[self presentMediaPlayerControllerWithURL:[self getAudioUrl] options:nil completion:^(BOOL didPlayToEnd, NSTimeInterval endTime, NSError * _Nullable error) {
NSLog(#"Error = %#",error);
}];
}
You can get the audio url from the App Groups.
- (NSURL *)getAudioUrl
{
// Getting the audio url from the App Groups
NSURL *container = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:APP_GROUP_IDENTIFIER];
NSURL *outputURL = [container URLByAppendingPathComponent:[NSString stringWithFormat:DIRECTORY_PATH]];
return outputURL;
}
Hope this will fix your issue.

How to add image in PHAsset and delete it from photo library?

I am working on an app like hiding photos and I want to move the images to my app so for that I have to import images from photo library and delete that image from library but I cant understand how to work with PHAssets and where to implement.
I used the UIPickerview to pick the image and then delete it from library please anyone can help me for that
This the picker where I get image :
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
And this is for delete but what is asset :
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets:formatWithOrientation];
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished deleting asset. %#", (success ? #"Success." : error));
}];
Try this code. It's working for me.
PHFetchResult *asset = [PHAsset fetchAssetsWithALAssetURLs:#“Your asset url” options:nil];
[asset enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%#",[obj class]);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
BOOL req = [obj canPerformEditOperation:PHAssetEditOperationDelete];
if (req) {
NSLog(#"true");
[PHAssetChangeRequest deleteAssets:#[obj]];
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished Delete asset. %#", (success ? #"Success." : error));
if (success) {
NSLog(#“delete successfully”);
}
}];
}];

uiWebView printing a pdf

Inside of uiwebview, what is a good way print a pdf document?
The pdf is accessible via a url or it can be loaded inside of an iframe.
Using the standard javascript widnow.print() functions will not work.
I am considering using a javascript bridge such as:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *URL = [request URL];
if ([[URL scheme] isEqualToString:#"native"]) {
NSString *urlString = [[request URL] absoluteString];
NSArray *urlParts = [urlString componentsSeparatedByString:#":"];
NSString *cmd = [urlParts objectAtIndex:1];
if ( [cmd isEqualToString:#"printPdf"] ) {
// [self dosomething];
}
}
return YES;
}
At this point I need some sort of xcode function which accept a path to the pdf and send it the airPrinter.
Is this a good approach? I am searching examples of how to print a pdf inside a uiWebView.
As I've earned the tumbleweed badge for no up votes and no responses, I'll post my solution.
This fetches the pdf doc and opens the airPrint dialog--all within a uiWebView.
So if IOS would simply allow the javascript window.print() to function inside of uiWebView, my app would not be setting in the app store waiting for approval and re-release.
Anyway, here's a working solution:
- (void)printInit:(NSString *)parm {
UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
if(!controller){
NSLog(#"Couldn't get shared UIPrintInteractionController!");
return;
}
NSString *base = #"https://someurl.com/";
NSString *ustr = [base stringByAppendingString:parm];
//NSURL *url = [NSURL fileURLWithPath:ustr];
NSURL *url = [NSURL URLWithString:ustr];
NSData *thePdf = [NSData dataWithContentsOfURL:url];
controller.printingItem = thePdf;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = #"PDFDoc";
controller.printInfo = printInfo;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(#"FAILED! error = %#",[error localizedDescription]);
}
};
CGRect rect = CGRectMake(310, 5, 100, 5);
[controller presentFromRect:rect inView:self.webView animated:YES completionHandler:completionHandler];
}

Cacheing UIImage as NSData and getting it back

I'm trying to cache images I load from Flickr. If I load the same image, I'm hoping to use the cached version instead. For some reason, when I download an image from the internet, it works, but if I load it from my cache, it displays a blank image. I checked cacheData, and it has the same amount of bits as the image I put in, so it appears loading the file is working.
Here is how I cache images:
+ (void)cachePhoto:(NSData *)photo withKey:(NSString *)key {
if (photo) {
NSArray * urlArray = [fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];
NSURL * targetDirectory = (NSURL *)[urlArray objectAtIndex:0];
targetDirectory = [targetDirectory URLByAppendingPathComponent:key];
[photo writeToURL:targetDirectory atomically:YES];
[cachedPhotos addObject:key];
NSLog(#"target url %#", targetDirectory);
}
}
+ (NSData *)photoInCache:(NSString *)key {
if ([cachedPhotos containsObject:key]) {
NSString * path = [[cacheDirectory URLByAppendingPathComponent:key] path];
NSLog(#"path: %#", path);
return [fileManager contentsAtPath:path];
} else {
return nil;
}
}
And my code to get it back:
NSData * cacheData = [PhotoCache photoInCache:key];
if (cacheData) {
self.imageView.image = [UIImage imageWithData:cacheData];
[spinner stopAnimating];
NSLog(#"used cached image");
} else {
dispatch_queue_t downloadQueue = dispatch_queue_create("get photo from flickr", NULL);
dispatch_async(downloadQueue, ^{
NSData * imageData = [[NSData alloc] initWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
self.imageView.image = [UIImage imageWithData:imageData];
[PhotoCache cachePhoto:imageData
withKey:key];
});
});
}
I figured it out - I was loading the image into the imageView in my prepareForSegue, where the ImageView was not yet loaded. I loaded the image in viewDidLoad and it worked. I also had to use UIImagePNGRepresentation, like suggested in the comments.