EXC_BAD_ACCESS on retriving NSData - iphone

In my app I am using the camera and photo library to get an UIImage...After picking the image I need to convert it to NSData and wants to pass this data to a method called addBlobToContainer:....but it gives the EXC_BAD_ACCESS....
How can I resolve this?
Here is my code for photo library...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
image.image = [info objectForKey:#"UIImagePickerControllerEditedImage"];
imageData = [NSData dataWithData:UIImageJPEGRepresentation(image.image,1)];
guid = [Guid randomGuid];
NSLog(#"%#", guid.description);
GUID = guid.description;
NSLog(#"GUID===%#",GUID);
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"STRIMAGEDATA===%#",imageData);
if ([imageData length] != 0)
{
NSLog(#"%#",imageData);
[client addBlobToContainer:newcontainer blobName:GUID contentData:imageData contentType:#"application/octet-stream" withBlock:^(NSError *error)
{
if (error)
{
NSLog(#"%#",[error localizedDescription]);
}
else
{
NSLog(#"blob inserted suuccessfully…");
imageURL = [serviceURL stringByAppendingString:[NSString stringWithFormat:#"%#.jpg",GUID]];
NSLog(#"IMAGEURL=%#",imageURL);
}
}];-->EXC_BAD_ACCESS
}
}

You are not accessing a property, you are accessing the variable behind the property. If you want the data to be automatically retained by the property, use property setters, e.g. self.imageData = ... instead of imageData = ....

Try
self.imageData = UIImageJPEGRepresentation(image.image,1);

Related

Listing All Folder content from Google Drive

Hi I have integrated google Dive with my app using Dr. Edit sample code from google drive. But i am not able to view all the files, which are stored in my Google Drive account.
// I have tried this
-(void)getFileListFromSpecifiedParentFolder
{
GTLQueryDrive *query2 = [GTLQueryDrive queryForChildrenListWithFolderId:#"root"];
query2.maxResults = 1000;
[self.driveService executeQuery:query2
completionHandler:^(GTLServiceTicket *ticket,
GTLDriveChildList *children, NSError *error)
{
NSLog(#"\nGoogle Drive: file count in the folder: %d", children.items.count);
if (!children.items.count)
{
return ;
}
if (error == nil)
{
for (GTLDriveChildReference *child in children)
{
GTLQuery *query = [GTLQueryDrive queryForFilesGetWithFileId:child.identifier];
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFile *file,
NSError *error)
{
NSLog(#"\nfile name = %#", file.originalFilename);}];
}
}
}];
}
//I want to Display All content in NSLog...
1. How to get all files from Google Drive.
First in viewDidLoad: method check for authentication
-(void)viewDidLoad
{
[self checkForAuthorization];
}
And here is the definition of all methods:
// This method will check the user authentication
// If he is not logged in then it will go in else condition and will present a login viewController
-(void)checkForAuthorization
{
// Check for authorization.
GTMOAuth2Authentication *auth =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientId
clientSecret:kClientSecret];
if ([auth canAuthorize])
{
[self isAuthorizedWithAuthentication:auth];
}
else
{
SEL finishedSelector = #selector(viewController:finishedWithAuth:error:);
GTMOAuth2ViewControllerTouch *authViewController =
[[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
clientID:kClientId
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:finishedSelector];
[self presentViewController:authViewController animated:YES completion:nil];
}
}
// This method will be call after logged in
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth: (GTMOAuth2Authentication *)auth error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
if (error == nil)
{
[self isAuthorizedWithAuthentication:auth];
}
}
// If everthing is fine then initialize driveServices with auth
- (void)isAuthorizedWithAuthentication:(GTMOAuth2Authentication *)auth
{
[[self driveService] setAuthorizer:auth];
// and finally here you can load all files
[self loadDriveFiles];
}
- (GTLServiceDrive *)driveService
{
static GTLServiceDrive *service = nil;
if (!service)
{
service = [[GTLServiceDrive alloc] init];
// Have the service object set tickets to fetch consecutive pages
// of the feed so we do not need to manually fetch them.
service.shouldFetchNextPages = YES;
// Have the service object set tickets to retry temporary error conditions
// automatically.
service.retryEnabled = YES;
}
return service;
}
// Method for loading all files from Google Drive
-(void)loadDriveFiles
{
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = [NSString stringWithFormat:#"'%#' IN parents", #"root"];
// root is for root folder replace it with folder identifier in case to fetch any specific folder
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *files,
NSError *error) {
if (error == nil)
{
driveFiles = [[NSMutableArray alloc] init];
[driveFiles addObjectsFromArray:files.items];
// Now you have all files of root folder
for (GTLDriveFile *file in driveFiles)
NSLog(#"File is %#", file.title);
}
else
{
NSLog(#"An error occurred: %#", error);
}
}];
}
Note: For get full drive access your scope should be kGTLAuthScopeDrive.
[[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
clientID:kClientId
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:finishedSelector];
2. How to download a specific file.
So for this you will have to use GTMHTTPFetcher. First get the download URL for that file.
NSString *downloadedString = file.downloadUrl; // file is GTLDriveFile
GTMHTTPFetcher *fetcher = [self.driveService.fetcherService fetcherWithURLString:downloadedString];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error)
{
if (error == nil)
{
if(data != nil){
// You have successfully downloaded the file write it with its name
// NSString *name = file.title;
}
}
else
{
NSLog(#"Error - %#", error.description)
}
}];
Note: If you found "downloadedString" null Or empty just have look at file.JSON there are array of "exportsLinks" then you can get the file with one of them.
3. How to upload a file in specific folder: This is an example of uploading image.
-(void)uploadImage:(UIImage *)image
{
// We need data to upload it so convert it into data
// If you are getting your file from any path then use "dataWithContentsOfFile:" method
NSData *data = UIImagePNGRepresentation(image);
// define the mimeType
NSString *mimeType = #"image/png";
// This is just because of unique name you can give it whatever you want
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd-MMM-yyyy-hh-mm-ss"];
NSString *fileName = [df stringFromDate:[NSDate date]];
fileName = [fileName stringByAppendingPathExtension:#"png"];
// Initialize newFile like this
GTLDriveFile *newFile = [[GTLDriveFile alloc] init];
newFile.mimeType = mimeType;
newFile.originalFilename = fileName;
newFile.title = fileName;
// Query and UploadParameters
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:data MIMEType:mimeType];
GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:newFile uploadParameters:uploadParameters];
// This is for uploading into specific folder, I set it "root" for root folder.
// You can give any "folderIdentifier" to upload in that folder
GTLDriveParentReference *parentReference = [GTLDriveParentReference object];
parentReference.identifier = #"root";
newFile.parents = #[parentReference];
// And at last this is the method to upload the file
[[self driveService] executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error){
NSLog(#"Error: %#", error.description);
}
else{
NSLog(#"File has been uploaded successfully in root folder.");
}
}];
}

Upload Photo from iphone app to rails server

I am building an iphone app that lets users upload photos to a rails-backed web service.
I am testing the app on my device and I am able to take a photo then post it- however the photoData is returned as null.
This is the xcode log after creating a post:
post = {
content = Test;
"created_at" = "2013-08-02T19:15:05Z";
id = 2;
photo = {
thumb = {
url = "<null>";
};
"thumb_retina" = {
url = "<null>";
};
url = "<null>";
};
};
success = 1;
}
What am I missing from the implementation to actually post the data to the server?
On the rails side I am using carrierwave and miniMagick as uploaders and using :fog storage to save everything to S3. (That is the goal at least- but that isn't happening.)
My post model has these properties:
#property (nonatomic, strong) NSString *content;
#property (nonatomic, strong) NSString *thumbnailUrl;
#property (nonatomic, strong) NSString *largeUrl;
#property (nonatomic, strong) NSData *photoData;
The save method is like this:
- (void)saveWithProgressAtLocation:(CLLocation *)location
withBlock:(void (^)(CGFloat))progressBlock completion:(void (^)(BOOL, NSError *))completionBlock {
if (!self.content) self.content = #"";
NSDictionary *params = #{
#"post[content]" : self.content,
};
NSURLRequest *postRequest = [[APIClient sharedClient] multipartFormRequestWithMethod:#"POST"
path:#"/posts"
parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFileData:self.photoData
name:#"post[photo]"
fileName:#""
mimeType:#"image/png"];
}];
AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
CGFloat progress = ((CGFloat)totalBytesWritten) / totalBytesExpectedToWrite;
progressBlock(progress);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (operation.response.statusCode == 200 || operation.response.statusCode == 201) {
NSLog(#"Created, %#", responseObject);
NSDictionary *updatedPost = [responseObject objectForKey:#"post"];
[self updateFromJSON:updatedPost];
[self notifyCreated];
completionBlock(YES, nil);
} else {
completionBlock(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completionBlock(NO, error);
}];
[[APIClient sharedClient] enqueueHTTPRequestOperation:operation];
}
And the actual method that gets called onSave in the photoViewController is this:
- (void)save:(id)sender {
Post *post = [[Post alloc] init];
post.content = self.contentTextField.text;
post.photoData = UIImagePNGRepresentation(self.imageView.image);
[self.view endEditing:YES];
ProgressView *progressView = [ProgressView presentInWindow:self.view.window];
if (location) {
[post saveWithProgressAtLocation:self.locationManager.location withBlock:^(CGFloat progress) {
[progressView setProgress:progress];
} completion:^(BOOL success, NSError *error) {
[progressView dismiss];
if (success) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(#"ERROR: %#", error);
}
}];
}
The problem is that the photoData is not saved to the server. Any ideas why?
Initially I had a precompiled default photo in rails: assets/images/nophoto.png - but any time I took a picture, this default would override the new photo and get posted, which is obviously not what I want. So I deleted that, and now I am getting null.
Any ideas?
Convert image to Data then Encode to Base64 String the save that string in server and then when retrieving from server, decode Base64 String to data and use [UIImage imageWithData: data];

how can i check if NSUrl is a valid image url?

I'm using SDWebImage library and I have this code:
[cell.imgLogo setImageWithURL:[NSURL URLWithString:[item objectForKey:#"s_logo"]] placeholderImage:[UIImage imageNamed:#"default.png"]];
I have tweak the library SDWebImage a little bit to ignore empty string or a NSUrl with empty string in method downloadWithURL: delegate: options: userInfo::
if ([url isKindOfClass:NSString.class])
{
if ([(NSString *)url length] > 0) {
url = [NSURL URLWithString:(NSString *)url];
} else {
return;
}
}
else if (![url isKindOfClass:NSURL.class])
{
url = nil; // Prevent some common crashes due to common wrong values passed like NSNull.null for instance
}
else if ([url isKindOfClass:NSURL.class]) {
if ([[url absoluteString] length] > 0) {
//valid url
} else {
return;
}
}
So now it works with empty string and just to display its default image but the problem is when it comes to a string that is not an image url like:
http://beta.xxxxxxx.com/gangnamwe?to=boko
It displays nothing, it removes the placeholder image and displays nothing.
So how will I identify a valid image url? or is there any better work around for this?
Your help are much appreaciated.
you can check after getting NSData from NSURL . You can use GCD to download data
here is an example i created which save your image in photo library.
dispatch_async(dispatch_queue_create("com.getImage", NULL), ^(void) {
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKII9COB-hvMef4Zvb9XYVbXKDFZHJAHwwzzGyMiy_b-q65GD43Chd37jH"]];
UIImage *image=[UIImage imageWithData:data];
if (image==nil) {
//yourImageURL is not valid
image=[UIImage imageNamed:#"placeholder.png"];
}
else{
//yourImageURL is valid
dispatch_async(dispatch_get_main_queue(), ^{
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
//show your image
});
}
});
There is method in NSURL to check if the file exsists.
- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error
Example
NSURL *theURL = [NSURL URLWithString:string];
NSError *err;
if ([theURL checkResourceIsReachableAndReturnError:&err] == NO)
{
NSLog(#"resource not reachable");
}
Here's a category on NSURL for you :
// nsurl+documentTypes.h
#interface NSURL (documentTypes)
- (BOOL)isImageType;
#end
// nsurl+documentTypes.m
#implementation NSURL (documentTypes)
- (BOOL)isImageType
{
NSString * UTI = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,(__bridge CFStringRef)[self pathExtension],NULL);
return UTTypeConformsTo((__bridge CFStringRef)UTI, kUTTypeImage);
}
#end
You can check if the url ends with some image name or not.You can get the parts of the url in following way:
NSURL* url = [NSURL URLWithString:#"http://digg.com/news/business/24hr"];
NSString* reducedUrl = [NSString stringWithFormat:
#"%#://%#/%#",
url.scheme,
url.host,
[url.pathComponents objectAtIndex:1]];
Now, take the last object of the pathComponents and check if it contains .png or .jpg etc.
In Swift:
import Foundation
public extension NSURL {
public var isImage: Bool {
return UTI.map{ UTTypeConformsTo($0, kUTTypeImage) } ?? false
}
public var UTI: String? {
var value: AnyObject?
let _ = try? getResourceValue(&value, forKey: NSURLTypeIdentifierKey)
return value as? String
}
}
e.g:
let url = NSURL(fileURLWithPath: "/Users/i/Desktop/image.png")
url.isImage //--> true

Using the YouTube API and iPhone SDK, how would I get information about a search result?

I'm trying to simply search for videos using a query, which is working perfectly using the below code.
// Create a service object for executing queries
GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
// Services which do not require sign-in may need an API key from the
// API Console
service.APIKey = #"AIzaSy...";
// Create a query
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = searchBar.text;
query.videoEmbeddable = #"true";
query.type = #"video";
//query.country = #"US";
// Execute the query
GTLServiceTicket *ticket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
// This callback block is run when the fetch completes
if (error == nil) {
GTLYouTubeSearchListResponse *products = object;
[videoArray removeAllObjects];
// iteration of items and subscript access to items.
for (GTLYouTubeSearchResult *item in products) {
NSMutableDictionary *dictionary = [item JSONValueForKey:#"id"];
NSLog(#"%#", [dictionary objectForKey:#"videoId"]);
YoutubeVideo *video = [[YoutubeVideo alloc]init];
[video setLblTitle:item.snippet.title];
//Get youtube video image
[video setImgIconURL:[NSURL URLWithString:item.snippet.thumbnails.defaultProperty.url]];
[video setLblVideoURL:[dictionary objectForKey:#"videoId"]];
[video setLblChannelTitle:item.snippet.channelTitle];
[videoArray addObject:video];
}
reloadData = YES;
[tableView reloadData];
//Download images asynchronously
[NSThread detachNewThreadSelector:#selector(downloadImages)
toTarget:self
withObject:nil];
}else{
NSLog(#"Error: %#", error.description);
}
}];
However, now I'd like to display certain information about the video. Some of this information I can get out of
item.snippet
But I also need to get the video duration, and number of views. How can I get them using Youtube API 3.0?? I also had an idea to try using GData just for this, but it literally triples the load time to use
NSString *JSONString = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://gdata.youtube.com/feeds/api/videos/%#?v=2&alt=json", [video lblVideoURL]]] encoding:NSUTF8StringEncoding error:nil ];
How do I get the duration of the video, plus the number of views the video has?
Search query only accept ID and Snippet as parts. If you change to Video List Query you can include other parts, but you have to use one of the filters.
I think you'll have to get the video ID with the search query and do another query (Now a video query) filtering by ID (the Id you got), than you can get all other information of the videos you searched.
The problem is i'm having trouble getting the video ID, i think the API use the word "identifier" instead of "id" because it's a reserved word of objective-c.
Edit: Yeah, it was just a matter of time, just request my GTLYoutubeSearchResponse.JSON, an manipulated it as i wanted.
FIRST QUERY:
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = #"iphone";
query.fields = #"items(id,snippet)";
query.order = #"viewCount";
//query.channelId = #"UCsnbNwitAF9BzjjdMfRyK2g";//Kavaco
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
appDelegate.videos = object;
[self performSegueWithIdentifier:#"videoList" sender:self];
}
else {
NSLog(#"%#", error.description);
}
}];
SECOND QUERY: In my TableViewController, inside my cellForRowAtIndexPath i do another query for each video i found. Be sure to request only the variables you need to avoid spending your credits, in my case i requested only viewCount.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
GTLYouTubeVideo *video = appDelegate.videos[indexPath.row];
NSMutableDictionary *videoIdJson = [video.JSON objectForKey:#"id"];
NSString *videoId = [videoIdJson objectForKey:#"videoId"];
cell.textLabel.text = video.snippet.title;
GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosListWithPart:#"statistics"];
query.identifier = videoId;
query.maxResults = 1;
query.fields = #"items/statistics(viewCount)";
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
GTLYouTubeVideoListResponse *detalhe = object;
NSMutableDictionary *responseJSON = detalhe.JSON;
NSArray *tempArray = [responseJSON objectForKey:#"items"];
NSMutableDictionary *items = tempArray[0];
NSMutableDictionary *statistics = [items objectForKey:#"statistics"];
_views = [[NSString alloc] initWithFormat:#"Views: %#",[statistics objectForKey:#"viewCount"]];
cell.detailTextLabel.text = _views;
}
else {
NSLog(#"%#", error.description);
}
}];
cell.detailTextLabel.text = _views;
return cell;
}
Hope it helps.
Collect the id from search API and do another video list API call is the proper way to do what you want to achieve. The video list API call can put multiple video ids separate by comma in the same call. The extra call shouldn't consider exhausting because this is expected behavior on API v3:
Project Member #1 je...#google.com
That's the expected behavior, and not likely to change. Since the
search.list() method can return channels, videos, and playlists, only
properties that make sense for all of those resource types are
returned in the search responses. If you need to obtain any other
properties, making a follow-up request to, e.g., videos.list() is
required. Note that you can pass in up to 50 video ids to
videos.list(), so you can effectively look up an entire page's worth
of search.list() results in a single video.list() call.
If you try https://developers.google.com/youtube/v3/docs/videos/list#try-it , you set contentDetails,statistics as the part, you should able to get the following result:
"contentDetails": {
"duration": "PT20M38S",
"dimension": "2d",
"definition": "hd",
"caption": "false",
"licensedContent": false
},
"statistics": {
"viewCount": "191",
"likeCount": "7",
"dislikeCount": "0",
"favoriteCount": "0",
"commentCount": "0"
}
PT20M38S means 20 minutes and 38 seconds, based on ISO 8601(http://en.wikipedia.org/wiki/ISO_8601)
The best way for make this is:
if (!service) {
service = [[GTLServiceYouTube alloc] init];
service.shouldFetchNextPages = YES;
service.shouldFetchInBackground = YES;
service.retryEnabled = YES;
service.APIKey = #"AIzaSyDSO2JPnM_r9VcDrDJJs_d_7Li2Ttk2AuU";
}
[youtubeList removeAllObjects];
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id"];
query.maxResults = 50;
query.q = withText;
query.fields = #"items(id)";
query.order = #"viewCount";
query.type = #"video";
// query.videoDuration = #"long";//any-long-medium-short
__block NSInteger incrementRequest = 0;
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *idsResponse = object;
for (GTLYouTubeVideoListResponse *videoInfo in object) {
[youtubeList addObject:videoInfo.JSON];
GTLQueryYouTube *query2 = [GTLQueryYouTube queryForVideosListWithIdentifier:[[videoInfo.JSON valueForKey:#"id"] valueForKey:#"videoId"] part:#"id,contentDetails,snippet,statistics"];
query2.maxResults = 1;
query2.fields = #"items(id,contentDetails,snippet,statistics)";
query2.order = #"viewCount";
[service executeQuery:query2 completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *detalhe = object;
for (NSMutableDictionary *tmpDict in youtubeList) {
if ([[[tmpDict valueForKey:#"id"] valueForKey:#"videoId"] isEqualToString:[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"id"]]) {
[tmpDict removeObjectForKey:#"id"];
//condition personal
if (![Utils parseISO8601TimeIsGrater30:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"duration"]]) {
BOOL isBlockedInUs = NO;
for (NSString *countryRestric in [[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"regionRestriction"] valueForKey:#"blocked"]) {
if ([countryRestric isEqualToString:#"US"]) {
isBlockedInUs = YES;
break;
}
}
if (!isBlockedInUs) {
[tmpDict addEntriesFromDictionary:detalhe.JSON];
[tmpDict setValue:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"snippet"] valueForKey:#"publishedAt"] forKey:#"publishedAt"];
} else {
[youtubeList removeObject:tmpDict];
}
} else {
[youtubeList removeObject:tmpDict];
}
break;
}
}
incrementRequest ++;
if ([idsResponse.items count] == incrementRequest) {
//Finish
[self.tableView reloadData];
}
}];
}
}];

getting NULL cache

I am working with NSCache in iOS i have following code in .h file for cache:
NSCache *_cache;
I am adding the image which are downloading from the url to the cache in .m:
-(void)cacheFromURL:(NSURL*)url
{
[_cache setCountLimit:50];
UIImage* newImage = [_cache objectForKey:url.description];
if( !newImage )
{
NSError *err = nil;
if(url!=Nil)
{
newImage=[UIImage imageWithData:[NSData dataWithContentsOfURL:url options:0 error:&err]];
}
if( newImage )
{
[_cache setValue:newImage forKey:url.description];
}
else
{
NSLog( #"UIImageView:LoadImage Failed: %#", err );
}
if(_cache==Nil)
{
NSLog(#"nil");
}
else
{
NSLog(#"cache is not nil");
}
}
}
But i am getting the nil cache every time . where i can see the downloading process in log .
why am i getting null cache?
You need to create/initialize the NSCache object before you can add and object to it. Also you need to add object with the setObject:forKey:
You have to initialize your NSCache object first:
_cache = [[NSCache alloc] init];