NSUrlConnection hangs on didReceiveData, but not always - iphone

I have a issue while downloading an image from the web.
I have a uitableview with fullscreen cells, every cell background is an image downloaded from the web using an array of urls.
The problem occurs only on the FIRST cell for the first time where the image doesnt load, but if I scroll down to the second cell and then go scroll up again to the first it loads successfully!
The app stucks on this method :
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"receiving data");
[downloadData appendData:data];
}
I have an iPhone 4s with iOS6 and this problem doesnt occur and the image loads perfectly.
Any suggestions?
Thanks in advance
EDIT
with my UIImageViewDownload.m that extends UIImageView
- (void) loadImage{
NSURLRequest *request= [NSURLRequest requestWithURL:myurl];
NSURLConnection *conn= [NSURLConnection connectionWithRequest:request delegate:self];
if(conn){
NSLog(#"Sto scaricando");
downloadData=[[NSMutableData alloc]init];
indicator= [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[indicator setFrame:CGRectMake(0, 0, 30, 30)];
[indicator setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)];
[self addSubview:indicator];
[indicator startAnimating];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"ricevo data");
[downloadData appendData:data];
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"finisco data");
UIImage *img= [UIImage imageWithData:downloadData];
[self setImage:img];
[indicator stopAnimating];
}

Related

Add UIProgressView to a TableView Cell

I have an app that presents Table View of different files. I have it set up to Asynchronously download, and would like to have the selected cell show a progress bar. I've looked online all afternoon, and everything I have found so far seems real incomplete on how to do this. Here is my code so far for the download, and set up to have a progressview show download status.
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:entry.articleUrl];
self.nameit = entry.articleTitle;
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
receivedData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
}
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
progress.hidden = NO;
[receivedData setLength:0];
expectedBytes = [response expectedContentLength];
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
float progressive = (float)[receivedData length] / (float)expectedBytes;
[progress setProgress:progressive];
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[connection release];
}
- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse: (NSCachedURLResponse *)cachedResponse {
return nil;
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:[currentURL stringByAppendingString:#".mp3"]];
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[receivedData writeToFile:pdfPath atomically:YES];
progress.hidden = YES;
[connection release];
}
First, add an UIProgressView variable to you interface, so that you can reference to it from any method in your class.
Then, when user selects it. you have to initialize it
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];
progress = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
progress.frame = CGRectMake(10, 10, 30, 30);
progress.progress = 0.0;
progress.center = CGPointMake(23,21);
[cell.contentView addSubview:progress];
}
Now you can update a progressBar as the file downloads and after it just send[progress removeFromSuperView]
That's it!

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

UIActivityIndicatorView for an UIImage that load for an URL

I have an UIImage that is loaded from a URL, and i want to show an UIActivityIndicatorView animating while the image loads. Someone can help me?
Thanks for all.
So u want to use the UIActivityIndicator while accessing the server.
First create the indicator while the connection call, and when connection didfinishloading remove the activity indicator
//call this when connection start
UIActivityIndicator *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = CGRectMake(140, 236, 37, 37);
[activityIndicator startAnimating];
[self.view addSubview:activityIndicator];
self.view.userInteractionEnabled = NO;
//remove activity indicator while connection did finish loadin
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
self.view.userInteractionEnabled = YES;
}
First of all add Activity indicator in xib and connect object of the UIActivity Indicator.
Click "Hides when Stopped" in the xib.
Then,
-(void)FetchFromServer
{
NSURLRequest* updateRequest = [NSURLRequest requestWithURL: [NSURL URLWithString:#"Write Your Url Here"]];
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:updateRequest delegate:self];
[connection start];
[activityIndicator startAnimating];
}
And then in the delegate,
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
UIImage *img = [UIImage imageWithData: data];
myImageView.image=img;
[activityIndicator stopAnimating];
}

iPhone My program crashes after it play a mp4 file using the

I am making a program that loads videos from a server and then saves them locally. The programmed worked fine when i was doing it synchronizely. When I changed it to do it asynchronously , it would crash when the person return to the pre screen and try to press any of the buttons with a sig bad memory error.
What happens is the vedio loads and plays ok. When they click the done button the methed
- (void) moviePlayBackDidFinish:(NSNotification*)notification;{
[ mp stop];
// [ mp release];
[self dismissModalViewControllerAnimated: true];
}
exicutes and it goes to the pre screen. Now on the pre screen, if they click on any button, i get a
I did the following
1. the file is big so I chnage my
[[NSMutableData alloc] initWithLebngth:0]; to [[NSMutableData alloc] initWithCapacity:200000];, did not work.
- (void)viewDidLoad {
[super viewDidLoad];
// construct the url
NSString *mServerName=[ [ NSString alloc] initWithString:#"http://www.besttechsolutions.biz/projects/golfflix/" ];
NSString *mFullName=[ mServerName stringByAppendingString: mVedioName ];
NSURL *movieUrl=[[NSURL alloc] initWithString:mFullName];
// start the transmision
NSURLRequest *theRequest = [NSURLRequest requestWithURL:movieUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
receivedData = [[NSMutableData alloc] initWithCapacity:100000000];
connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
[movieUrl release];
[mServerName release];
}
///////////////////////////////////////////////////////////////////////////////////////////////
// background loading
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[receivedData setLength:0];
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[connection release];
}
- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[connection release];
/////////////////////////////////////////////////////////////////////////////////
// Save vedio
NSFileManager *mFile= [NSFileManager defaultManager];
NSString *filename=[ NSHomeDirectory() stringByAppendingPathComponent:mVedioName];
[mFile createFileAtPath:filename contents: receivedData attributes:nil];
[ receivedData release ];
// play it
NSURL *fileUrl=[ NSURL fileURLWithPath:filename];
if (mp==nil)
{
mp=[[MPMoviePlayerController alloc] initWithContentURL: fileUrl];
[mp.view setFrame: self.view.bounds];
[self.view addSubview: mp.view];
// Set movie player layout
[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setFullscreen:YES];
// May help to reduce latency
[mp prepareToPlay];
[mp play];
}
else {
[mp stop];
mp.contentURL=fileUrl;
[mp play];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
// movie reced save to file
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification;{
[ mp stop];
// [ mp release];
[self dismissModalViewControllerAnimated: true];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
any thoughts on this would be GREAT, ben stuck for days!!!!
Ted
If you are coming back to the pre screen then try to shift your code to
-(void)viewWillAppear:(BOOl)animated
{
//code
}
because the function viewDidLoad will be called only one time when the view is loaded.
but the function viewWillAppear will be called whenever that view will appear.

Is there a way to add Loading View before reload tableview data

I am trying to add Loading data option in viewDidLoad() function before [self.tableview reloaddata]. I am not sure how to add it and is there a way to make the user know that there is data getting loaded.
I am parsing JSON file and the data gets loaded on 3G pretty slow, so its the better way to allow user to know that data is being loaded with loading option. Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Add the view controller's view to the window and display.
responseData = [[NSMutableData data] retain];
self.twitterArray = [NSMutableArray array];
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:#"http://search.twitter.com/search.json?q=mobtuts&rpp=5"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[super viewWillAppear:animated];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *results = [responseString JSONValue];
self.twitterArray = [results objectForKey:#"results"];
[self.tableView reloadData]; // How to add loading view before this statement
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.twitterArray count];
}
I'm not quite sure what you mean by "loading view" but i guess you mean an activity indicator or something else what should be presented while you are loading data.
make an ivar UIActivityIndicatorView *myLoadingView;
Init it in viewDidLoad
myLoadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
myLoadingView.hidesWhenStopped = YES;
[myLoadingView stopAnimating];
[self.view addSubView:myLoadingView];
show the view before you start your connection [myLoadingView startAnimating];
hide it again when the download was finished by stoping it in the delegate method connectionDidFinishLoading: after [self.tableView reloadData]; [myLoadingView stopAnimating];
release it in viewDidUnload [myLoadingView release];
Feel free to ask if you have questions or if i had misunderstood you.