Loading image from url ios 8 objective c - objective-c

i´m trying to obtain the imagen from this url[#"file:///var/mobile/Media/DCIM/100APPLE/IMG_0158.JPG"], but i can´t.
Always is nil.
this is my code:
NSData *data = [NSData dataWithContentsOfURL: #"file:///var/mobile/Media/DCIM/100APPLE/IMG_0158.JPG"];
UIImage *image = [UIImage imageWithData:data];
self.pruebaTmp.image = image;
i obtain the url with this code:
if (asset) {
// get photo info from this asset
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
NSURL *path = [info objectForKey:#"PHImageFileURLKey"];
//asignamos el path de la imágen seleccionada en galeria
self.pathImagen = path;
}];
}
if someone could help i would be very grateful, because i can´t load the image with the url obtained.

you can`t not get UIimage or metadata from that url.
you can get UIImage from local Identifier of access
PHFetchResult *savedAssets = [PHAsset fetchAssetsWithLocalIdentifiers:#[localIdentifier] options:nil];
[savedAssets enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
//this gets called for every asset from its localIdentifier you saved
//PHImageRequestOptionsDeliveryModeHighQualityFormat
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = NO;
imageRequestOptions.deliveryMode = PHImageRequestOptionsResizeModeFast;
imageRequestOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager]requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:imageRequestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
NSLog(#"get image from result");
if (result) {
}
}];
imageRequestOptions = nil;
}];

Related

Get all Images from Live Photo

I want to get a NSArray with all the UIImage from a Live Photo to create a GIF of that. I tried to make screenshots while animating the live photo but it doesn't work.
Can anyone help me?
Thanks!
First step, you need convert a Live Photo to Video, using this:
PHAssetResourceManager.defaultManager().writeDataForAssetResource(assetRes,
toFile: fileURL, options: nil, completionHandler:
{
// Video file has been written to path specified via fileURL
}
Finally, using this library to convert this to GIF, or you can search in google for another way: https://github.com/NSRare/NSGIF
Hope this will help you.
This is what I did to achieve the same thing as you requested.
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
options.predicate = [NSPredicate predicateWithFormat:#"mediaType == %d", PHAssetMediaTypeImage];
options.predicate = [NSPredicate predicateWithFormat:#"mediaSubtype == %d", PHAssetMediaSubtypePhotoLive];
options.includeAllBurstAssets = NO;
PHFetchResult *allLivePhotos = [PHAsset fetchAssetsWithOptions:options];
NSLog(#"Get total live count : %ld",(unsigned long)allLivePhotos.count);
NSMutableArray *arrAllLiveImagesGroups = [NSMutableArray array];
for (PHAsset *asset in allLivePhotos) {
[asset requestContentEditingInputWithOptions:nil
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *urlMov = [contentEditingInput.livePhoto valueForKey:#"videoURL"];
NSMutableArray *arrLive = [NSMutableArray array];
NSMutableArray *arrSingleLiveImagesGroup = [NSMutableArray array];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:urlMov options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.requestedTimeToleranceAfter = kCMTimeZero;
generator.requestedTimeToleranceBefore = kCMTimeZero;
for (Float64 i = 0; i < CMTimeGetSeconds(asset.duration) * 5 ; i++){
#autoreleasepool {
CMTime time = CMTimeMake(i, 5);
NSError *err;
CMTime actualTime;
CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&err];
UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image scale:1.0 orientation:UIImageOrientationDown];
[arrLive addObject:generatedImage];
CGImageRelease(image);
}
}
[arrSingleLiveImagesGroup addObject:arrLive];
[arrAllLiveImagesGroups addObject:arrSingleLiveImagesGroup];
}];
}

How to edit metadata of image in iOS8?

ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
[lib assetForURL:nil resultBlock:^(ALAsset *asset) {
NSDictionary *metadata = rep.metadata;
if (metadata) {
NSDictionary *GPSDict=metadata[#"{GPS}"];
NSDictionary *TIFFDict=metadata[#"{TIFF}"];
if (GPSDict){
double longitude = [[GPSDict objectForKey:#"Longitude"] doubleValue];
double latitude = [[GPSDict objectForKey:#"Latitude"] doubleValue];
if ([[GPSDict objectForKey:#"LatitudeRef"] isEqualToString:#"S"]) {
latitude = -latitude;
}
if ([[GPSDict objectForKey:#"LongitudeRef"] isEqualToString:#"W"]) {
longitude = -longitude;
}
if (TIFFDict){
NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];
[pref setObject:[TIFFDict objectForKey:#"DateTime"] forKey:#"PHOTODATE"];
[pref synchronize];
}
coordinate2D = CLLocationCoordinate2DMake(latitude, longitude);
}else {
latitude = locationManager.location.coordinate.latitude;
longitude = locationManager.location.coordinate.longitude;
[GPSDictionary setObject:[NSNumber numberWithFloat:fabs(latitude)]
forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSDictionary setObject:(latitude > 0 ? #"N": #"S") forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
[GPSDictionary setObject:[NSNumber numberWithFloat:fabs(longitude)]
forKey:(NSString*)kCGImagePropertyGPSLongitude];
[GPSDictionary setObject:(longitude > 0 ? #"E": #"W") forKey:(NSString*)kCGImagePropertyGPSLongitudeRef]; //
if (metadata&& GPSDictionary) {
[metadata setValue:GPSDictionary forKey:(NSString*)kCGImagePropertyGPSDictionary];
}
coordinate2D = CLLocationCoordinate2DMake(latitude, longitude);
}
}
else
{
}
} failureBlock:^(NSError *error) {
//User denied access
NSLog(#"Unable to access image: %#", error);
}];
I am using above code to get metadata of image.But now i want to edit this metadata.I want to add custom location in image if the location information is not present in the {GPS} dictionary.
From the apple’s documentation : Applications are only allowed to edit assets that they originally wrote. So if your application is writing image in Photos Library then only you will be able to edit its metadata.
You can check whether metadata is editable or not using ALAsset’s editable property.
I was able to update metadata using setImageData:metadata:completionBlock: method.
Please refer following code :
I am passing same image data with updated metadata. Also I have tested changing orientation not the GPS data but this code helps you to start :
ALAsset *asset = // your asset
if(asset.editable) {
NSDictionary *metadata = asset.defaultRepresentation.metadata;
NSDictionary *gpsInfo=metadata[#"{GPS}"];
if (gpsInfo) {
NSMutableDictionary *mutableGPSInfo = [gpsInfo mutableCopy];
[mutableGPSInfo setObject:#"yourNewLatitude" forKey:#"Latitude"];
[mutableGPSInfo setObject:#"yourNewLongitude" forKey:#"Longitude"];
NSMutableDictionary *mutableMetadata = [metadata mutableCopy];
[mutableMetadata setObject:[mutableGPSInfo copy] forKey:#"{GPS}"];
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
[asset setImageData:data metadata:[mutableMetadata copy] completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(#"Error : %#",error);
} else {
NSLog(#"Asset metadata is successfully edited");
}
}];
}
} else {
NSLog(#"oops..! Asset can not be edited");
}

How to trim Music Library file and save it document directry

-(BOOL)trimAudioFileAtPath:(NSString *)inputFilename
start:(float)start
end:(float) stop{
NSString *outputFilename = #"File Path";
NSError *error = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:outputFilename]) {
if (![fileManager removeItemAtPath:outputFilename error:&error]) {
DebugLog(#"error file remove:%#",error); } else {
DebugLog(#"sucess remove file");
} }
NSURL *audioFileInput = [NSURL fileURLWithPath:inputFilename];
NSURL *audioFileOutput = [NSURL fileURLWithPath:outputFilename];
if (!audioFileInput || !audioFileOutput){ return NO; }
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVMutableComposition *mutableComposition = [AVMutableComposition composition]; // Create the video composition track.
AVMutableCompositionTrack *mutableCompositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSLog(#"audioFileInput %#",audioFileInput); AVURLAsset *assetUrl = [AVURLAsset assetWithURL:audioFileInput];
if ([[assetUrl tracksWithMediaType:AVMediaTypeAudio] count]==0) { return NO; }
// Get the first music track from each asset. AVAssetTrack *audioAssetTrack = [[assetUrl tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; [mutableCompositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,audioAssetTrack.timeRange.duration) ofTrack:audioAssetTrack atTime:kCMTimeZero error:nil];
// we need the audio asset to be at least 50 seconds long for this snippet
CMTime startTime = CMTimeMake(start, 1);
CMTime stopTime = CMTimeMake(stop, 1);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime,stopTime);
Float64 duration = CMTimeGetSeconds(exportTimeRange.duration);
// Create the export session with the composition and set the preset to the highest quality.
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A];
if (duration > 6.0){
AVMutableAudioMix *mutableAudioMix = [AVMutableAudioMix audioMix];
// Create the audio mix input parameters object.
AVMutableAudioMixInputParameters *mixParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:mutableCompositionAudioTrack];
// float totalDutaion=mutableComposition.duration.value;
float totalDutaion=duration;
float lenth=totalDutaion/3;
CMTime startCM = CMTimeMake(totalDutaion-lenth-1,mutableComposition.duration.timescale);
CMTime endCM = CMTimeMake(lenth, mutableComposition.duration.timescale);
// Set the volume ramp to slowly fade the audio out over the duration of the composition.
[mixParameters setVolumeRampFromStartVolume:0.f toEndVolume:1.f timeRange:CMTimeRangeMake(startTime, endCM)];
[mixParameters setVolumeRampFromStartVolume:1.f toEndVolume:0.f timeRange:CMTimeRangeMake(startCM,endCM)];
// Attach the input parameters to the audio mix.
mutableAudioMix.inputParameters = #[mixParameters];
exportSession.audioMix=mutableAudioMix; }
if (exportSession == nil){
return NO; }
exportSession.outputURL = audioFileOutput; exportSession.outputFileType = AVFileTypeAppleM4A; exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^ {
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
// It worked!
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
// It failed...
} }]; return YES; }
I am using this function to trim the music file from music libaray. The Above code is working file when I try to trim a file which is located in bundle. But When I try to use the same function with input file from iTune music Library it is give no Tracks i.e. if ([[assetUrl tracksWithMediaType:AVMediaTypeAudio] count]==0) {
return NO;
} return No. Can anyone help to trim music from iTunes Libaray
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
if (mediaItemCollection) {
NSLog(#"%#",[mediaItemCollection items]);
// [musicPlayer setQueueWithItemCollection: mediaItemCollection];
// [musicPlayer play];
}
[KVNProgress showWithStatus:#"Processing"];
MPMediaItem *item =mediaItemCollection.representativeItem;
NSURL* assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
// set up an AVAssetReader to read from the iPod Library
AVURLAsset *songAsset =
[AVURLAsset URLAssetWithURL:assetURL options:nil];
NSError *assetError = nil;
AVAssetReader *assetReader =[AVAssetReader assetReaderWithAsset:songAsset error:&assetError];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AVAssetReaderOutput *assetReaderOutput =[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil];
if (! [assetReader canAddOutput: assetReaderOutput]) {
NSLog (#"can't add reader output... die!");
return;
}
[assetReader addOutput: assetReaderOutput];
// NSArray *dirs = NSSearchPathForDirectoriesInDomains
// (NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
// NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:#"out.m4a"];
NSString * exportPath =[NSString stringWithFormat:#"%#%#", NSTemporaryDirectory(), #"out.m4a"];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath
error:nil];
}
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
AVAssetWriter *assetWriter =[AVAssetWriter assetWriterWithURL:exportURL
fileType:AVFileTypeCoreAudioFormat
error:&assetError];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
NSDictionary *outputSettings =[NSDictionary dictionaryWithObjectsAndKeys:
#(kAudioFormatLinearPCM), AVFormatIDKey,
#44100.0, AVSampleRateKey,
#2, AVNumberOfChannelsKey,
[NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)],AVChannelLayoutKey,
#16, AVLinearPCMBitDepthKey,
#NO, AVLinearPCMIsNonInterleaved,
#NO,AVLinearPCMIsFloatKey,
#NO, AVLinearPCMIsBigEndianKey,
nil];
AVAssetWriterInput *assetWriterInput =[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings];
if ([assetWriter canAddInput:assetWriterInput]) {
[assetWriter addInput:assetWriterInput];
} else {
NSLog (#"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime = NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime: startTime];
__block UInt64 convertedByteCount = 0;
dispatch_queue_t mediaInputQueue =
dispatch_queue_create("mediaInputQueue", NULL);
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock: ^
{
while (assetWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer =
[assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
// append buffer
[assetWriterInput appendSampleBuffer: nextBuffer];
// update ui
convertedByteCount +=
CMSampleBufferGetTotalSampleSize (nextBuffer);
} else {
// done!
[assetWriterInput markAsFinished];
[assetWriter finishWritingWithCompletionHandler:^{
[assetReader cancelReading];
[self performSelectorOnMainThread:#selector(updateCompletedAtMusicPath:)
withObject:exportPath
waitUntilDone:NO];
// NSLog (#"done. file size is %llu",[outputFileAttributes fileSize]);
}];
break;
}}}];
[self dismissViewControllerAnimated:NO completion:^{
}];
}
This is code used for geting the URL form iTune Library and story in document directry
First i just want to point out that you can just read segments of the audio from the library by setting the timeRange property of your assetReader. This way instead of copying over the whole file first you can just copy the segments you need. That being said, if you are going to stick with your original implementation, i think you just need to change AVURLAsset *assetUrl = [AVURLAsset assetWithURL:audioFileInput]; to AVURLAsset *assetUrl = [[AVURLAsset URLAssetWithURL:audioFileInput options:nil];
I Got sucess to save itune music in document libray by using following Method
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
self.fullPathToFileForAudio = [documentsDirectory stringByAppendingPathComponent:#"auto-old.m4a"];
NSFileManager *fileMgr = [NSFileManager defaultManager];
// get rid of existing mp4 if exists...
if ([fileMgr removeItemAtPath:self.fullPathToFileForAudio error:&error] != YES)
NSLog(#"Unable to delete file: %#", [error localizedDescription]);
[self convertVideoToLowQuailtyWithInputURL:self.musicUrl outputURL:[NSURL fileURLWithPath:self.fullPathToFileForAudio] handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
NSLog(#"completed %#",exportSession.error);
printf("completed\n");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(#"%# PATH",self.fullPathToFileForAudio);
[self exporterCompleted:[NSURL fileURLWithPath:self.fullPathToFileForAudio]];
});
}
else
{
// NSLog(#"%#",exportSession.error);
printf("error\n");
dispatch_sync(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
}
}];
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
CMTime startTime = CMTimeMake(minValue, 1);
CMTime stopTime = CMTimeMake(maxValue, 1);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = outputURL;
exportSession.outputFileType = #"com.apple.m4a-audio";
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
}];
}

Image not displayed on UICollectionViewCell

I am trying to get images on contacts,here i used UICollectionViewCell but in the collection view i didn't get image for the contact,i get only name and number.Here my code is
- (IBAction)ContactDisplay:(id)sender {
_addressBookController = [[ABPeoplePickerNavigationController alloc] init];
[_addressBookController setPeoplePickerDelegate:self];
[self presentViewController:_addressBookController animated:YES completion:nil];
}
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person
{
[self displayPerson:person];
}
- (void)displayPerson:(ABRecordRef)person
{
NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person,
kABPersonFirstNameProperty);
NSLog(#"%#",name);
NSString* phone = nil;
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person,
kABPersonPhoneProperty);
if (ABMultiValueGetCount(phoneNumbers) > 0) {
phone = (__bridge_transfer NSString*)
ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
} else {
phone = #"[None]";
}
NSLog(#"%#",phone);
UIImage *img ;
if (person != nil && ABPersonHasImageData(person)) {
if ((&ABPersonCopyImageDataWithFormat) != nil ) {
img= [UIImage imageWithData:(__bridge NSData *)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail)];
}
} else {
NSString *imageUrlString = #"http://www.google.co.in/intl/en_com/images/srpr/logo1w.png";
NSURL *url = [NSURL URLWithString:imageUrlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
img= [UIImage imageWithData:data];
}
NSString *string ;//
string =[NSString stringWithFormat:#"%#",img];
NSLog(#"%#",img);
self.name.text=name;
self.number.text=phone;
[self.nameArray addObject:name];
[self.imageArray addObject:string];
NSLog(#"%#",self.nameArray);
NSLog(#"%#",self.imageArray);
[self.collectionView reloadData];
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
}
finally an image array i got like this
(
"add-button.png",
"<UIImage: 0x17e56c80>, {148, 148}"
)
On image array every image like display .PNG format it will display fine ,then how can modify it.
Can you please suggest me how can you solve this,thank you.
I don't fully agree with everything you're doing there but I think you're getting your data wrong. Try using this instead when you're fetching the ABPerson image data.
if (person != nil) {
CFDataRef imageData = ABPersonCopyImageData(person);
NSData *data = CFBridgingRelease(imageData);
if (data != nil && data.length > 10){ //arbitrary length to make sure our data object isnt' really empty
img = [UIImage imageWithData:data];
} else {
NSString *imageUrlString = #"http://www.google.co.in/intl/en_com/images/srpr/logo1w.png";
NSURL *url = [NSURL URLWithString:imageUrlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
img= [UIImage imageWithData:data];
}
Then don't store your images as Strings in your array. Store them either as NSData or UIImage, but NOT STRINGS.
so
[myArray addObject:img]; //not the string.
And when you fetch it later, make sure you treat is as an image and not as a string
on your storyboard, select the image and look at the properties panel.
there are "Installed" options at the bottom. check the topmost "Installed" box.
I think there might be issue with conversion of image to string
NSString *string ;//
string =[NSString stringWithFormat:#"%#",img];
Add image to image array without converting to string
[self.imageArray addObject:img];
I do it like this in my app. Assuming 'person' is an ABRecordRef.
NSMutableDictionary *contactInfoDict = [[NSMutableDictionary alloc]
initWithObjects:#[#"", #"", #"", #""]
forKeys:#[#"firstName", #"lastName", #"birthday", #"picture"]];
CFTypeRef generalCFObject;
// Firtname
generalCFObject = ABRecordCopyValue(person, kABPersonFirstNameProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:#"firstName"];
CFRelease(generalCFObject);
}
// Lastname
generalCFObject = ABRecordCopyValue(person, kABPersonLastNameProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:#"lastName"];
CFRelease(generalCFObject);
}
// Birthday
generalCFObject = ABRecordCopyValue(person, kABPersonBirthdayProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:#"birthday"];
NSLog(#"Date : %#", [contactInfoDict objectForKey:#"birthday"]);
CFRelease(generalCFObject);
}
// User image
CFDataRef photo = ABPersonCopyImageData(person);
if (photo) {
CFRelease(photo);
UIImage *image = [UIImage imageWithData:(__bridge NSData*)photo];
[contactInfoDict setObject:image forKey:#"picture"];
}

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.