Set progress bar for downloading NSData - ios

NSURL *url = [NSURL URLWithString:#"http://i0.kym-cdn.com/entries/icons/original/000/005/545/OpoQQ.jpg?1302279173"];
NSData *data = [NSData dataWithContentsOfURL:url];
imageView.image = [[[UIImage imageWithData:data];
I want to set progress bar while downloading.

To give a more detailed example:
in your .h file do
#interface YourClass : YourSuperclass<NSURLConnectionDataDelegate>
in your .m file do
#property (nonatomic) NSMutableData *imageData;
#property (nonatomic) NSUInteger totalBytes;
#property (nonatomic) NSUInteger receivedBytes;
And somewhere call
NSURL *url = [NSURL URLWithString:#"http://i0.kym-cdn.com/entries/icons/original/000/005/545/OpoQQ.jpg?1302279173"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
And also implement the delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) urlResponse;
NSDictionary *dict = httpResponse.allHeaderFields;
NSString *lengthString = [dict valueForKey:#"Content-Length"];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSNumber *length = [formatter numberFromString:lengthString];
self.totalBytes = length.unsignedIntegerValue;
self.imageData = [[NSMutableData alloc] initWithCapacity:self.totalBytes];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.imageData appendData:data];
self.receivedBytes += data.length;
// Actual progress is self.receivedBytes / self.totalBytes
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
imageView.image = [UIImage imageWithData:self.imageData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//handle error
}

You can't get progress call backs by using that method.
You need to use an NSURLConnection and NSURLConnectionDataDelegate.
The NSURLConnection then runs asynchronously and will send callbacks to its delegate.
The main ones to look at are...
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
and
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
These are all used for getting the connection to do what you're already doing.
EDIT
Actually, see Marc's answer below. It is correct.

You can use MBProgress Hud class for loading view. You can download only two classes from here :-https://github.com/jdg/MBProgressHUD
After you write this code in that class which you want to load the data
Example :In your viewDidLoad you write this
- (void) viewDidLoad
{
MBProgressHud *spinner = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
spinner.mode = MBProgressHUDModeCustomView;
[spinner setLabelText:#"Loading....."];
[spinner setLabelFont:[UIFont systemFontOfSize:15]];
[spinner show:YES];
  [self performSelectorInBackground:#selector(getData) withObject:nil];
}
- (void) getData
{
NSURL *url = [NSURL URLWithString:#"http://i0.kym-cdn.com/entries/icons/original/000/005/545/OpoQQ.jpg?1302279173"];
NSData *data = [NSData dataWithContentsOfURL:url];
imageView.image = [[[UIImage imageWithData:data];
[spinner hide:YES];
[spinner removeFromSuperViewOnHide];
}

Related

Fetch Pagination URL Data with NSURLConnection in iOS

i am newbie in iOS make an app that contain JSON Parsing data for that i use NSURLConnection and fetch data but here my URL Contain Pagination so, i want to fetch pagination data when tableView scroll for that i write a code like as
- (void)viewDidLoad
{
page=0;
NSString *path = [NSString stringWithFormat:#"http://isp.ebizzprojects.com/webservices/testimonial.php?page=%d",page];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:path]];
[NSURLConnection connectionWithRequest:request delegate:self];
}
And Also I send second request when my table view scroll like as
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger currentOffset = scrollView.contentOffset.y;
NSInteger maximumOffset = scrollView.contentSize.height- scrollView.frame.size.height;
if (maximumOffset - currentOffset <= 0)
{
page = page + 1;
[self getData];
}
}
-(void)getData
{
NSString *path = [NSString stringWithFormat:#"http://isp.ebizzprojects.com/webservices/testimonial.php?page=%d",page];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:path]];
[NSURLConnection connectionWithRequest:request delegate:self];
}
And NSURLConnection delegate method like as
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[_parsedData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_parsedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
_parsedData = nil;
_parsedData = [[NSMutableData alloc]init];
[[[UIAlertView alloc]initWithTitle:#"Alert!" message:#"Connection Error" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil]show];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString =[[NSString alloc]initWithData:_parsedData encoding:NSUTF8StringEncoding];
NSDictionary *loDict = [responseString JSONValue];
self.responceArray=[loDict valueForKey:#"description"];
self.nameArray=[loDict valueForKey:#"name"];
self.testimonialTable.hidden=FALSE;
[self.testimonialTable reloadData];
}
From this my code when i scroll table view then i got only second page data i want to keep both data in to my table view when my tableview scroll please give me solution for this.
Thanks.
You need to add new items to array like, create NSMutableArray for self.responceArray and self.nameArray
[self.responceArray addObjectsFromArray:[loDict valueForKey:#"description"]];
[self.nameArray addObjectsFromArray:[loDict valueForKey:#"name"]];

Is there an event for when a UIImage has finished loading

I am displaying a UIImage view with this code:
NSURL *imageUrl = [[NSURL alloc]initWithString:#"http://..."];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageUrl];
UIImage *audioArt =[[UIImage alloc] initWithData:imageData];
UIImageView *artView =[[UIImageView alloc] initWithImage:audioArt];
artView.contentMode = UIViewContentModeScaleAspectFit;
artView.autoresizesSubviews = NO;
artView.frame = viewRef.bounds;
[artView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[artView setBackgroundColor:[UIColor blackColor]];
[viewRef setBackgroundColor:[UIColor blackColor]];
[viewRef addSubview:artView];
Is there an event in Objective C to tell when this UIImage has finished loading or when the UIImageView has finished displaying the image?
Many thanks.
in your .h
#interface YourClass : YourSuperclass<NSURLConnectionDataDelegate>
#property (nonatomic) NSMutableData *imageData;
#property (nonatomic) NSUInteger totalBytes;
#property (nonatomic) NSUInteger receivedBytes;
And somewhere call
NSURL *imageUrl = [[NSURL alloc]initWithString:#"http://..."];
NSURLRequest *request = [NSURLRequest requestWithURL: imageUrl];
NSURLConnection *connection = [NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
And also implement the delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) urlResponse;
NSDictionary *dict = httpResponse.allHeaderFields;
NSString *lengthString = [dict valueForKey:#"Content-Length"];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSNumber *length = [formatter numberFromString:lengthString];
self.totalBytes = length.unsignedIntegerValue;
[self.imageData = [[NSMutableData alloc] initWithLength:self.totalBytes];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.imageData appendData:data];
self.receivedBytes += data.length;
// Actual progress is self.receivedBytes / self.totalBytes
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
imageView.image = [UIImage imageWithData:self.imageData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//handle error
}
Update:
Since NSMutableData initWithLength: creates a data object whose raw data is filled with zeros, replace initWithLength: with just init and it will works.
UIImage doesn't have any delegate or callback which tells you about its successful loading.
If you are getting the image from any url, you can use NSURL's delegates and notifications to track if you received the image or not.
Also you can achieve it as :
- (void)loadImage:(NSString *)filePath {
[self performSelectorInBackground:#selector(loadImageInBackground:) withObject:filePath];
}
- (void)loadImageInBackground:(NSString *)filePath {
#autoreleasepool{
UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
[self performSelectorOnMainThread:#selector(didLoadImageInBackground:) withObject:image waitUntilDone:YES];
}
}
- (void)didLoadImageInBackground:(UIImage *)image {
self.imageView.image = image;
}

how to store json data from url in ios device and to use local it

I want to use json in my application. I can parse json from url with this code :
#import "ViewController.h"
#implementation ViewController
{
NSDictionary *titles;
NSMutableData *Data;
NSArray *fileContent;
NSArray *folderContent;
NSMutableArray *all;
}
#synthesize Table;
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url =[NSURL URLWithString:#"http://192.168.1.100/veis/root/developers/api/filemanager.php?key=5147379269&getlist=root"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc]initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
Data = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[Data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
titles = [NSJSONSerialization JSONObjectWithData:Data options:kNilOptions error:nil];
fileContent = [titles objectForKey:#"fileContent"];
folderContent = [titles objectForKey:#"folderContent"];
all = [[NSMutableArray alloc]init];
[all addObjectsFromArray:folderContent];
[all addObjectsFromArray:fileContent];
[Table reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"The Connection has been LOST" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
but I want when I dont have internet I can to use of json. I dont know how to use of json in way offline (or local in my device)
can you guide me in this issue that how to use json in way offline
The way parsing should be same for Online and Offline json data, both are same, just you need to write a file using Unparsed data say data.json in Documents Directory, if you want to use the same process to use json, but if you want to use parsed json, then write it as plist..
You can try to use the following methods
-(void)saveJsonWithData:(NSData *)data{
NSString *jsonPath=[[NSSearchPathForDirectoriesInDomains(NSUserDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingFormat:#"/data.json"];
[data writeToFile:jsonPath atomically:YES];
}
-(NSData *)getSavedJsonData{
NSString *jsonPath=[[NSSearchPathForDirectoriesInDomains(NSUserDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingFormat:#"/data.json"];
return [NSData dataWithContentsOfFile:jsonPath]
}
Then call the function as
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self saveJsonWithData:data];
}

Show Activity Indicator when fetching JSON data

I am beginner in IOS programming. My question is my app fetching data from JSON in my web server, when starting the apps, it is slightly lag and delay due to the fetching process, so i would like to show activity indicator when i connecting to JSON data. How can i do that?
My JSON coding:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *urlAddress = [NSURL URLWithString:#"http://emercallsys.webege.com/RedBoxApp/getEvents.php"];
NSStringEncoding *encoding = NULL;
NSError *error;
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:urlAddress usedEncoding:encoding error:&error];
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict)
{
eventsDetail = [[dict objectForKey:#"eventsDetail"] retain];
}
[jsonreturn release];
}
use the following code
//add a UIActivityIndicatorView to your nib file and add an outlet to it
[indicator startAnimating];
indicator.hidesWhenStopped = YES;
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
//Load the json on another thread
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:urlAddress usedEncoding:encoding error:NULL];
[jsonreturn release];
//When json is loaded stop the indicator
[indicator performSelectorOnMainThread:#selector(stopAnimating) withObject:nil waitUntilDone:YES];
});
You can use something like below code:
- (void)fetchData
{
[activityIndicator startAnimating];
NSURL *url = [NSURL URLWithString:strUrl];
NSURLRequest *theRequest = [[NSURLRequest alloc]initWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(theConnection) {
}
else {
NSLog(#"The Connection is NULL");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
webData = [[NSMutableData data] retain];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[webData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"ERROR with theConenction %#",error);
UIAlertView *connectionAlert = [[UIAlertView alloc] initWithTitle:#"Information !" message:#"Internet / Service Connection Error" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[connectionAlert show];
[connectionAlert release];
[connection release];
[webData release];
return;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
//NSLog(#"Received data :%#",theXML);
//[theXML release];
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary: webData error:&error];
if (dict) {
eventsDetail = [[dict objectForKey:#"eventsDetail"] retain];
}
[activityIndicator stopAnimating];
}

downloaded content using NSURLConnection does not display on my iPhone?

i am using NSURLConnection to download mp3 files from server, my code is
- (IBAction)download:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://viadj.viastreaming.net/start/psalmsmedia/ondemand/Nin%20snehamethrayo.mp3"];
NSLog(#"%#", url);
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;
[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;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"myFile.mp3"];
[receivedData writeToFile:documentsDirectoryPath atomically:YES];
[connection release];
}
when i click download button, the activity indicator start animating and stops after some time (i think it is downloading). but after that i can't find the downloaded file on my iPhone disk. actually where those files stored after downloading.
i have edited my info.plist to support iTunes file sharing.
is their any mistake with this code? or why can't i see the downloaded files?
My Created one class for downloading ringtones, See first RingtoneDwonloader.h file
import
#protocol RingtoneDownloaderDelegate
-(void)downloadingCompleted;
#end
#interface RingtoneDownloader : NSObject
{
NSMutableData *receivedData;
NSDate *connectionTime;
NSMutableString *diskPath;
id<RingtoneDownloaderDelegate>delegate;
}
#property(nonatomic, retain) iddelegate;
-(void)createUrlRequestForDownloadRingtone:(NSString *)urlString;
-(void)cancelDownloading;
#end
Now my RingtoneDownloader.m file,
import "RingtoneDownloader.h"
import "AppDelegate.h"
#interface RingtoneDownloader(){
AppDelegate *_appDelegate;
NSURLConnection *theConnection;
}
#end
#implementation RingtoneDownloader
#synthesize delegate;
-(void)createUrlRequestForDownloadRingtone:(NSString *)urlString{
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
theConnection =[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// This method is called when the server has determined that it
[receivedData setLength:0];
// long responseLength = [response expectedContentLength];
// NSLog(#"%ld", responseLength);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// release the connection, and the data object
[theConnection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
UIAlertView *alt = [[UIAlertView alloc] initWithTitle:#"" message:[NSString stringWithFormat:#"%#", [error localizedDescription]] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
// inform the user
NSLog(#"Connection failed! Error - %# %#", [error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
// release the connection, and the data object
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *soundFileName = _appDelegate.ringtoneURL;
NSString *soundFileextension = [soundFileName substringFromIndex:([soundFileName length]-3)];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", _appDelegate.ringtoneText, soundFileextension]];
NSData *imageData = (NSData *)receivedData;
NSError *err = nil;
BOOL isWriten = [imageData writeToFile:filePath options:NSDataWritingAtomic error:&err];
if(!isWriten){
NSLog(#"Ringtone not saved %#", [err localizedDescription]);
}
[theConnection release];
[receivedData release];
[delegate downloadingCompleted];
}
-(void)cancelDownloading{
[theConnection cancel];
[theConnection release];
[delegate downloadingCompleted];
}
Now u have to just created and instance of this class and set the delegate that i m create. That delegate give u information regarding your ringtone file is successfully downloaded or not.
Use iTunes file sharing in your app and copy the ringtone file to the app's documents directory.
Set "Application supports iTunes file sharing" to YES in your info.plist
The user can now access the ringtone via itunes and add it to their devices ringtones.

Resources