l[20]ve: invalid chunk type? - iphone

I don't know why I'm getting this error. I'm also getting an EXC_BAD_ACCESS issue from the following code. Any ideas why?
Running breakpoints on the didRecieveResponse and didRecieveData and didFinishLoading shows the first two get run and mid way through recieving data the program crashes.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// starts... :)
plistContentsData = [NSMutableData data]; //NSMutableData - inst in head
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[plistContentsData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
mellowListings = [[NSArray alloc] initWithData:plistContentsData]; //NSArray - inst in head
NSLog(#"%#",mellowListings);
CLLocationCoordinate2D newLocation;
int counter = 0;
for(NSDictionary *tempDict in mellowListings){
NSLog(#"%f",([[tempDict objectForKey:#"lat"] floatValue]));
NSLog(#"%f",([[tempDict objectForKey:#"long"] floatValue]));
newLocation.latitude = ([[tempDict objectForKey:#"lat"] floatValue]);
newLocation.longitude = ([[tempDict objectForKey:#"long"] floatValue]);
TCPlaceMarker *placemark = [[TCPlaceMarker alloc] initWithCoordinate:newLocation];
placemark.title = [tempDict objectForKey:#"name"];
placemark.subtitle = [tempDict objectForKey:#"address1"];
placemark.source = [[tempDict objectForKey:#"source"] lowercaseString];
placemark.tag = counter;
[mapView addAnnotation:placemark];
counter++;
}
}

plistContentsData = [NSMutableData data];
You create an autoreleased NSMutableData object and it may become invalid right after you exit didReceiveResponse method. You need to retain plistContentsData to fix that error.

Related

how to data fetch using json parsing in ios

I am beginner of iPhone developer. I want to display data from server I have used below source code..
-(void)loadData:(id)sender
{
self.requestdata=[NSMutableData data];
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:kLatestKivaLoansURL]];
[[NSURLConnection alloc]initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[requestdata setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[requestdata appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
self.requestdata=nil;
}
#pragma mark-
#pragma process loan data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responsedata=[[NSString alloc]initWithData:requestdata encoding:NSUTF8StringEncoding];
self.requestdata=nil;
NSDictionary *respDict = [[responsedata JSONValue]objectForKey:#"nodes"];
NSLog(#"Response Dict:%#",respDict);
NSMutableArray *arraY = [[NSMutableArray alloc]init];
arraY = [respDict mutableCopy];
NSLog(#"My array:%#",arraY);
NSString *mystr = [[[arraY objectAtIndex:0]valueForKey:#"node"]valueForKey:#"field_company_name_value"];
NSLog(#"Mystrname:%#",mystr);
NSArray *latestLoans=[(NSDictionary *)[responsedata JSONValue]objectForKey:#"responseData"];
NSLog(#"latest_dictionary:%#",latestLoans);
DisplayViewController *disp=[[DisplayViewController alloc]init];
for (int i = 0; i< [[latestLoans valueForKey:#"entries"] count] ; i++) {
// Search *aSearches = [[Search alloc] init];
NSDictionary *tempDict = [[latestLoans valueForKey:#"entries"] objectAtIndex:i];
// disp.link=[tempDict valueForKey:#"link"];
/*link = [tempDict valueForKey:#"link"];
aSearches.title = [tempDict valueForKey:#"title"];
aSearches.description = [tempDict valueForKey:#"contentSnippet"];
[appDelegate.search addObject:aSearches];*/
[appDelegate.disparray addObject:tempDict];
}
NSLog(#"DisplayArray:%#",appDelegate.disparray);
[self.view addSubview:disp.view];
/* DisplayViewController *disp=[[DisplayViewController alloc]initWithNibName:#"DisplayViewController" bundle:nil];
[self.navigationController pushViewController:disp animated:YES];*/
}
Please give any suggestion or source code which is apply in my code
Take a look at AFNetworking. It will do the job for you.
There is a specific method to handle JSON operations through the class AFJSONRequestOperation
Hope it helps.
http://www.touch-code-magazine.com/how-to-fetch-and-parse-json-by-using-data-models/
http://blog.zachwaugh.com/post/309924609/how-to-use-json-in-cocoaobjective-c
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
http://json.org/
This is great tutorial for beginner, pls read this tutorial.

Asynchronous NSURLConnection getting failed with auto mistypecasting of class instance

I am creating a single instance of a chase class which has a dictionary as a property.
As I add elements to dictionary, I can see the change in the count of dictionary keys.
But when I am accessing, it's firing a crash with message like given below:
[__NSCFString connection:didReceiveData:];
[__NSCFArray reqmap]; etc..
Basically, I am mapping request url with NSData instance, so that the response could be mapped and appended properly, asynchronously.
Code:
-(id)init
{
self = [super init];
if (self)
{
self.cacheDict = [[NSMutableDictionary alloc] initWithCapacity:20];
self.reqmap = [[NSMutableDictionary alloc] initWithCapacity:20];
}
return self;
}
+ (CommunityImageCache*)getSharedCommunityImageCache
{
if (sharedCommunityImageCacheInstance == nil) {
sharedCommunityImageCacheInstance = [[super allocWithZone:NULL] init];
}
return sharedCommunityImageCacheInstance;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString* keyurl = [[[connection currentRequest] URL] absoluteString];
//crash point >>>>
NSMutableData* tempdata = (NSMutableData*)[self.reqmap objectForKey:keyurl];
[tempdata appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection
{
NSString* keyurl = [[[theConnection currentRequest] URL] absoluteString];
NSMutableData* tempdata = [self.reqmap objectForKey:keyurl];
UIImage* img = [UIImage imageWithData:tempdata];
[self.cacheDict setObject:img forKey:[#"image:\\\\public\\" stringByAppendingString:keyurl]];
[self.reqmap removeObjectForKey:keyurl];
}
-(UIImage *)getImageFromUrl:(NSString *)url
{
UIImage* image = nil;
image = [self.cacheDict objectForKey:url];
if (!image)
{
image = [UIImage imageNamed:#"defaultProfile.png"];
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSString* localUrl = [NSString stringWithString:url];
NSString* finurl = [localUrl substringFromIndex:[#"image:\\\\public\\" length]];
UIImage* img = nil;
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:finurl]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSMutableData* data = [[NSMutableData alloc] init];
NSURLConnection* connect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
NSString* keyurl = [[[connect currentRequest] URL] absoluteString];
[self.reqmap setObject:data forKey:keyurl];
}
}
Needed badly, Thanks in advance.
Well, reqmap is suppose to contain NSMutableData objects, right ?
They need instantiation, something like :
[self.reqmap setValue:[[NSMutableData alloc] init] forKey:#"TheKey"];
You should also implement
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
when you're using NSURLConnection. I don't see it in your code above. Then you should alloc/reset the data in this function.
What is the actual error you are seeing? It sounds like either reqmap isn't an NSDictionary (though it is in your code above), or the object you're retrieving isn't a NSMutableData.
In total, implement:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection

UIActivityIndicatorView freeze

i have this function which call a function to check CMS for info. but the UIActivityIndicatorView freeze till the check is completed. not sure why.
EDIT: one thing funny, i commented out the performselector. the UIActivityIndicatorView still freezed. until i tapped my back button then it started to spin....
i'm using storyboard, iOS 5
-(void)showLoading
{
[activity startAnimating];
//loading is a label to show "File Loading"
loading.alpha =1;
//is a label to show a 0.3 alpha of the label
blackOverlay.hidden =0;
[self performSelector:#selector(updateFromInternet:) withObject:#"a" afterDelay:2];
//[self updateFromInternet:#"a"];
}
-(void)updateFromInternet:(NSString *)urlStr
{
NSString *URLString = #"http://sites.google.com/site/iphonesdktutorials/xml/Books.xml";
NSURL *updateDataURL = [NSURL URLWithString:URLString];
NSMutableURLRequest *WPXMLFetchRequest = [NSMutableURLRequest requestWithURL:updateDataURL];
self.receivedData = [NSMutableData data];
self.updateConnection = [NSURLConnection connectionWithRequest:WPXMLFetchRequest delegate:self];
NSLog(#"Checking update at : %#", updateDataURL);
//[self.updateConnection cancel];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
////NSlog(#"Receiving data");
[self.receivedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
////NSlog(#"Failed to receive data");
self.receivedData = nil;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
////NSlog(#"Received response from data");
[self.receivedData setLength:0];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *data=[[NSString alloc]initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(#"data %#",data);
NSError *parseError = nil;
//NSDictionary *xmlDict = [XMLReader dictionaryForXMLData:self.receivedData error:&parseError];
self.receivedDict = [XMLReader dictionaryForXMLData:self.receivedData error:&parseError];
[self showDataOnScrollView];
}
You should delay the "heavy" function a bit and let the Activity Indicator fire.
try adding a 2.0 and not 2 to your delay (I would use a much smaller value - say 0.3)
[self performSelector:#selector(updateFromInternet:) withObject:#"a" afterDelay:0.3];
if this does not solve's your problem you should look (or post) the code related to the extra stuff you have in your code like : loading.alpha =1; and blackOverlay.hidden =0; which I assume are elements added to the Activity Indicator

App crashed when downloading video

In my app im downloading some videos using NSURLConnection. It shows two memory warnings.
Received memory warning. Level=1
Received memory warning. Level=2
And then after sometime the App Crashes is there any way to solve this issue.
Can anyone help me with this issue.
Thanks in advance.
Code i used:
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:[exer1 objectAtIndex:i-1]]cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSLog(#"%# urlrequest ",theRequest);
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
HUD = [[MBProgressHUD showHUDAddedTo:self.view animated:YES] retain];
HUD.labelText =[NSString stringWithFormat:#"Downloading %d Video",[exer1 count]-(i-1)];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
}
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
expectedLength = [response expectedContentLength];
currentLength = 0;
HUD.mode = MBProgressHUDModeDeterminate;
NSLog(#"%d expectedLength",expectedLength);
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse.
// It can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is an instance variable declared elsewhere.
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
currentLength += [data length];
HUD.progress = currentLength / (float)expectedLength;
// Append the new data to receivedData.
// receivedData is an instance variable declared elsewhere.
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
[HUD hide:YES];
// release the connection, and the data object
// [connection release];
// receivedData is declared as a method instance elsewhere
// [receivedData release];
// inform the user
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
if(tempz == 1){
tempz =0;
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"The Internet connection appears to be offline." message:nil delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *err;
NSFileManager *fman = [NSFileManager defaultManager];
NSString *path = [[[fman URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path];
NSDictionary *fattr = [fman attributesOfFileSystemForPath:path error:&err];
//Error checking
NSUInteger freeSize = [[fattr objectForKey:NSFileSystemFreeSize] unsignedIntegerValue];
NSLog(#"Free Space %d", freeSize);
NSArray* paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
struct statfs tStats;
statfs([[paths1 lastObject] cString], &tStats);
float total_space = (float)(tStats.f_blocks * tStats.f_bsize);
NSLog(#"%f total_space",total_space);
[SavedVid addObject:[exer1 objectAtIndex:i-1]];
NSUserDefaults *currentDefaults6 = [NSUserDefaults standardUserDefaults];
[currentDefaults6 setObject:[NSKeyedArchiver archivedDataWithRootObject:SavedVid] forKey:#"SavedVid"];
[currentDefaults6 synchronize];
NSString* cacheDirectory = [NSHomeDirectory() stringByAppendingString:#"/Library/Caches"] ;
/* NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(#"%# documentsDirectory",documentsDirectory);
if (!documentsDirectory) {
NSLog(#"Documents directory not found!");
}
*/
NSString *file2 = [NSString stringWithFormat:#"%#/%#.mp4",cacheDirectory,[elementw.description objectAtIndex:i-1]];
/* NSLog(#"%# documentsDirectory",file2);
NSLog(#"%# ---- i elementw.description ---- %d ",elementw.description,i);
*/
[receivedData writeToFile:file2 atomically:YES];
NSLog(#" %# file 2 ",file2);
HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]] autorelease];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:2];
[self initializPlayer];
// release the connection, and the data object
// [connection release];
// [receivedData release];
}
When the data is received, you need to store it in a temporary (or not-so-temporary) file. The problem is that the whole file is being download into memory, which would consume most of the memory.
The application crashes because it's using too much memory, so writing to a file is the best option.
Something like this:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
currentLength += [data length];
HUD.progress = currentLength / (float)expectedLength;
NSString *temporaryFile = [NSString stringWithFormat:#"%#/fileDownload.part", NSTemporaryDirectory()];
if (![[NSFileManager defaultManager] fileExistsAtPath:temporaryFile]) {
[[NSFileManager defaultManager] createFileAtPath:temporaryFile contents:nil attributes:nil];
}
NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:temporaryFile];
[fileHandle seekToEndOfFile];
[fileHandle writeData:data];
[fileHandle closeFile];
if (currentLength == expectedLength) {
//read from the file stored at temporaryFile
//perhaps move to a permanent location and change
//its file name and extension.
}
}
I think you are keeping the Video in your memory. Depending on the size it can cause memory problems.

Need to call retain for a property with retain flag specified

I'm newbie in Objective-C, and as most of the newbies I have a questions about references management.
I've written a class which downloads data using NSURLConnection. The code is similar to Apple's example in http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html. The only difference is that receivedData variable is declared as "#property (nonatomic,retain) NSMutableData *receivedData;" In .m file I have "#synthesize receivedData = _receivedData;".
I have connectionStart function which starts downloading data. In this function I have this code:
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
self.receivedData = [NSMutableData data];
} else {
// Inform the user that the connection failed.
}
The program crashes with this message:
2011-06-12 12:47:22.298 WebGallery[1212:207] *** -[NSConcreteMutableData release]: message sent to deallocated instance 0x118a6fe0
If I change receivedData assignment to this code:
self.receivedData = [[NSMutableData data] retain];
Then the program works correctly and no memory leaks are detected.
As you see I need to call retain on NSMutableData and I'm using property, which is declared as "retain".
Why does this happen?
EDIT: Full contents of .m file:
#import "GalleryData.h"
#import "XmlParser.h"
#implementation GalleryData
#synthesize receivedData = _receivedData;
#synthesize imagesData = _imagesData;
#synthesize delegate = _delegate;
#synthesize currentObjectType = _currentObjectType;
#synthesize currentObjectIndex = _currentObjectIndex;
- (id) init
{
[super init];
_imagesData = [[NSMutableArray alloc] init];
return self;
}
- (void) dealloc
{
[_imagesData release];
_imagesData = nil;
[super dealloc];
}
- (void) connectionStart:(NSURL *)theURL
{
NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
//ASK: Kodėl čia reikia daryti retain jei #property jau nustatyta retain?
self.receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
}
}
- (void) startLoading
{
NSLog(#"Loading started");
self.currentObjectIndex = 0;
self.currentObjectType = ObjectTypeXML;
[self connectionStart:[NSURL URLWithString:#"http://www.aleksandr.lt/gallery/data.xml"]];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
[self.receivedData release];
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
if (self.currentObjectType == ObjectTypeXML) {
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:self.receivedData];
XmlParser *parser = [[XmlParser alloc] initXmlParser:self.imagesData];
[nsXmlParser setDelegate:parser];
[nsXmlParser parse];
[nsXmlParser release];
[parser release];
[self.receivedData release];
self.receivedData = nil;
if ([self.imagesData count]) {
self.currentObjectIndex = 0;
self.currentObjectType = ObjectTypeThumbImage;
ImageData *firstImage = [self.imagesData objectAtIndex:0];
NSURL *theURL = [NSURL URLWithString:firstImage.thumbImageURL];
[self connectionStart:theURL];
} else {
[self.delegate loadingFinished];
return;
}
} else if (self.currentObjectType == ObjectTypeThumbImage) {
ImageData *currentImage;
currentImage = [self.imagesData objectAtIndex:self.currentObjectIndex];
UIImage *thumbImage = [[UIImage alloc] initWithData:self.receivedData];
if (thumbImage == nil) {
NSLog(#"image was not created");
}
[currentImage setThumbImageScaled:thumbImage];
[thumbImage release];
[self.receivedData release];
self.receivedData = nil;
if (self.currentObjectIndex == ([self.imagesData count] - 1)) {
[self.delegate loadingFinished];
return;
}
self.currentObjectIndex++;
currentImage = [self.imagesData objectAtIndex:self.currentObjectIndex];
NSLog(#"'%#'", currentImage.thumbImageURL);
NSURL *theURL = [NSURL URLWithString:currentImage.thumbImageURL];
[self connectionStart:theURL];
}
}
#end
Do not call [self.receivedData release] - this leaves the internal pointer dangling. The whole point of a retained property is that it releases itself. Just do self.receivedData = nil.
Here is your problem:
[self.receivedData release];
self.receivedData = nil;
You're releasing the attribute twice (first time explicitly and second time implicitly by assigning nil).