I am working on upload images application which seems working fine for me. I am uploading 100 images. and when i run this process 4-5 times application crashes out.
This seems to me memory usage issue.. How to reduce that memory. I don't want to my application get crashed.
btn_Cancel.userInteractionEnabled=NO;
btn_Share.userInteractionEnabled=NO;
btn_Back.userInteractionEnabled=NO;
btn_BackTransp.userInteractionEnabled=NO;
btn_BareCode.userInteractionEnabled=NO;
[self integratedLoaderView];
NSURL *url=[NSURL URLWithString:#"http:/apiurl /"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
NSString *str_EstimateNumber=[NSString stringWithFormat:#"%#",txtFld_FolderName.text];
NSDateFormatter *formatter=[[NSDateFormatter alloc] init];
formatter.dateFormat=#"yyyy-MM-dd";
string=[formatter stringFromDate:[NSDate date]];
NSString *str_time;
formatter.dateFormat=#"hh.mm.ss a";
str_time=[formatter stringFromDate:[NSDate date]];
NSString *str_AppendString=[NSString stringWithFormat:#"%# at %#",string,str_time];
NSInteger str_Counter=[[NSString stringWithFormat:#"%lu",(unsigned long)[delegate.ary_ImageData count]] integerValue];
NSString *str_Value=[NSString stringWithFormat:#"%ld",(long)str_Counter];
NSString *str_Username=[NSString stringWithFormat:#"%#/Images",txtFld_SelectedFTP.text];
abc=0;
for (int i=0;i<[ary_Tosend count]; i++)
{
sleep(0.6);
abc++;
if ([str_ConnectionStatus isEqualToString:#"WiFi"])
{
}
if ([str_ConnectionStatus isEqualToString:#"Cellular"])
{
}
if ([str_ConnectionStatus isEqualToString:#"No Connection"])
{
btn_Cancel.userInteractionEnabled=YES;
btn_Share.userInteractionEnabled=YES;
btn_Back.userInteractionEnabled=YES;
btn_BackTransp.userInteractionEnabled=YES;
btn_BareCode.userInteractionEnabled=YES;
NSString *str_Total=[NSString stringWithFormat:#"%lu",(unsigned long)[ary_Tosend count]];
NSString *str_Saved=[NSString stringWithFormat:#"%lu",(unsigned long)[delegate.ary_ImageData count]];
NSInteger total_Count=[str_Total integerValue]-[str_Saved integerValue];
[self saveInDBWhenConnectionLost:total_Count];
[self ShowAlertForCheckInternetConnection];
return ;
}
if ([str_ConnectionStatus isEqualToString:#""])
{
btn_Cancel.userInteractionEnabled=YES;
btn_Share.userInteractionEnabled=YES;
btn_Back.userInteractionEnabled=YES;
btn_BackTransp.userInteractionEnabled=YES;
btn_BareCode.userInteractionEnabled=YES;
NSString *str_Total=[NSString stringWithFormat:#"%lu",(unsigned long)[ary_Tosend count]];
NSString *str_Saved=[NSString stringWithFormat:#"%lu",(unsigned long)[delegate.ary_ImageData count]];
NSInteger total_Count=[str_Total integerValue]-[str_Saved integerValue];
[self saveInDBWhenConnectionLost:total_Count];
[self ShowAlertForCheckInternetConnection];
return ;
}
NSString *str_fileName;
str_fileName=[NSString stringWithFormat:#"%#_%# %i.jpg",str_EstimateNumber,str_AppendString,abc];
NSDictionary *params=nil;
NSData *imageToUpload=UIImageJPEGRepresentation([ary_Tosend objectAtIndex:i],0.25);
NSString *encodedString=[NSString stringWithFormat:#"%#",[imageToUpload base64Encoding]];
params= #{
#"categoryName" :txtFld_Category.text,
#"folderName" :txtFld_FolderName.text,
#"fileName" :str_fileName,
#"userName" :str_Username,
#"postedFile" :encodedString,
#"accessToken" :#"Q)4%v59!#lyr"
};
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
httpClient.parameterEncoding = AFFormURLParameterEncoding;
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient setDefaultHeader:#"Accept" value:#"application/json"];
NSMutableURLRequest *request=[httpClient requestWithMethod:#"POST"
path:#"UploadImages/upload"
parameters:params];
NSURLResponse* response=nil;
NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
if(data.length)
{
NSString *responseString=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *error = nil;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if(responseString && responseString.length)
{
[delegate.ary_GetUploadedCount addObject:JSON];
[self responseUpload:JSON];
dispatch_async(dispatch_get_main_queue(),
^{
if(i < delegate.ary_ImageData. count)
{
[delegate.ary_ImageData removeObjectAtIndex:i];
[delegate.ary_TotalImages removeObjectAtIndex:i];
[ary_DataToConvert removeObjectAtIndex:i];
[ary_DataToConvert1 removeObjectAtIndex:i];
NSUserDefaults *default_AllImg=[NSUserDefaults standardUserDefaults];
[default_AllImg setValue:ary_DataToConvert forKey:#"ImageDetail"];
[default_AllImg synchronize];
NSUserDefaults *default_AllImg1=[NSUserDefaults standardUserDefaults];
[default_AllImg1 setValue:ary_DataToConvert1 forKey:#"ImageData"];
[default_AllImg1 synchronize];
}
});
}
}
}
});
Please tell me.
Make sure you factor your code so that you load an image into memory, upload it, and then release it. Don't build an array of all the images in memory at once.
If you've done that you might still have an autorelease problem.
You might try adding an auto release pool inside your loop:
for (NSString *filename in filenames)
{
#autoreleasepool
{
//Your code to load an image and upload it to the server goes here
}
}
However, it's a bit hard to give more specific help until you post your code.
EDIT
You are using NSURLConnection. That class has been deprecated. Use NSURLSession instead. That's not the cause of your problem. The cause of your problem is that your are queuing up 100 connections at the same time, with all of their data in memory.
You should use NSURLSession and an upload task. With an upload task you just provide a URL to the file and the system takes care of uploading it for you (and manages the memory for you.)
Related
This question already has an answer here:
Storing values in completionHandlers - Swift
(1 answer)
Closed 7 years ago.
I have a function that get data from server and it will run asynchronous while other function is running.
my problem, i called the function [self getdata] at viewdidload(). and NSLog at below the called function but the data is delay. it get null. may i know anyway to wait the function run finish only print out the data for me?
-(void)getdata
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *userID = [prefs objectForKey:#"userID"];
//get merged news
float latitude = [[prefs objectForKey:LAST_KNOWN_LATITUDE] floatValue];
float longitude = [[prefs objectForKey:LAST_KNOWN_LONGITUDE] floatValue];
NSInteger ref_id =[[[eventDict objectForKey:#"id"] substringFromIndex:2]integerValue];
NSInteger reference_EventType = [[eventDict objectForKey:#"type_id"]integerValue];
NSString *type =#"EVENT";
NSString *str = [NSString stringWithFormat:#"%#event.php", API_URL];
NSURL *URL = [NSURL URLWithString:str];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:URL];
__unsafe_unretained ASIFormDataRequest *_request = request;
[request setRequestMethod:#"POST"];
[request setPostValue:#"get_event_notification" forKey:#"tag"];
[request setPostValue:[NSNumber numberWithInteger:ref_id] forKey:#"reference_id"];
[request setPostValue:[NSNumber numberWithInteger:reference_EventType] forKey:#"reference_eventType"];
[request setPostValue:type forKey:#"reference_type"];
[request setPostValue:[NSNumber numberWithFloat:latitude] forKey:#"latitude"];
[request setPostValue:[NSNumber numberWithFloat:longitude] forKey:#"longitude"];
[request setPostValue:userID forKey:#"user_id"];
[request setDelegate:self];
[request setTimeOutSeconds:30.0];
[request setShouldAttemptPersistentConnection:NO];
[request startAsynchronous];
[request setCompletionBlock:^(void){
NSInteger responseCode = [_request responseStatusCode];
if (responseCode == 200 || responseCode == 201 || responseCode == 202)
{
//NSLog(#"%#", [_request responseString]);
NSMutableDictionary *response = (NSMutableDictionary *)[[_request responseString] JSONValue];
NSInteger success = [[response objectForKey:#"success"] integerValue];
if (success == 1)
{
if ([[response objectForKey:#"event"] isKindOfClass:[NSArray class]]) {
event = [[response objectForKey:#"event"] objectAtIndex:0];
dataArray=[event objectForKey:#"merged"];
NSLog(#"dataArray %d",dataArray.count);
mergedCount=[NSString stringWithFormat:#"%d",dataArray.count];
NSArray *pathsMergedCount = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryMergedCount = [pathsMergedCount objectAtIndex:0];
NSString *filePathMergedCount= [documentsDirectoryMergedCount stringByAppendingPathComponent:#"fileMergedCount.txt"];
[mergedCount writeToFile:filePathMergedCount atomically:TRUE encoding:NSUTF8StringEncoding error:NULL];
for(i=0;i<[dataArray count];i++)
{
feedDict=[dataArray objectAtIndex:i];
[eventIDMerged addObject:[feedDict objectForKey:#"event_id"]];
[eventDescMerged addObject:[feedDict objectForKey:#"description"]];
}
}}}
}];
[request setFailedBlock:^(void){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Failed" message:#"Internet connection too slow, please ensure you have a strong internet connection to have better user experience" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}];
}
-(void)viewDidLoad
{
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *pathsMergedCount = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryMergedCount = [pathsMergedCount objectAtIndex:0];
NSString *filePathMergedCount= [documentsDirectoryMergedCount stringByAppendingPathComponent:#"fileMergedCount.txt"];
NSString *strMergedCount = [NSString stringWithContentsOfFile:filePathMergedCount encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"Count3m %#",strMergedCount);
});
});
}
See my answer in this thread:
Storing values in completionHandlers - Swift
It includes a link to a full project (in Swift) demonstrating using completion handlers to manage async tasks.
I have an API GET Request that runs multiple times using a for loop. I am successfully able to create some NSStrings from this, but given that the loop, I need a good way to store it all together. So, at the end of the connectionRequest, I have it run another method, where I add the NSString to an NSMutableArray. However, when I check the contents of the NSMutableArray, it's only the most recent NSString in there. What am I missing?
- (void)viewWillAppear:(BOOL)animated {
for(int i = 0; i< self.theNumber; i++) {
[self getQuote];
}
}
-(void) getQuote {
NSString *bringitalltogether = #"URLOFAPI";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:bringitalltogether]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:60];
[request setHTTPMethod:#"GET"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSMutableDictionary *allResults = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:nil];
NSArray *book = [allResults valueForKey:#"bookname"];
self.bookstring = [book objectAtIndex:0];
NSArray *chapter = [allResults valueForKey:#"chapter"];
self.chapterstring = [chapter objectAtIndex:0];
NSArray *verse = [allResults valueForKey:#"verse"];
self.versestring = [verse objectAtIndex:0];
NSArray *text = [allResults valueForKey:#"text"];
self.textstring = [text objectAtIndex:0];
[self doneGotIt];
}
- (void) doneGotIt {
self.theArray = [[NSMutableArray alloc] init];
NSString *doIt = [NSString stringWithFormat:#"%# - %# %#:%#", self.textstring, self.bookstring, self.chapterstring, self.versestring];
[self.theArray addObject:doIt];
NSLog(#"%#", self.theArray);
}
The console shows the NSLog running the appropriate number of times, but each time, the array stays with just one verse, when I would expect it to gradually grow.
You are creating the new array instance every time. thats y , u are getting the last part.
- (void) doneGotIt {
//Create array only once if not yet created in memory
if (!self.theArray) {
self.theArray = [[NSMutableArray alloc] init];
}
NSString *doIt = [NSString stringWithFormat:#"%# - %# %#:%#", self.textstring, self.bookstring, self.chapterstring, self.versestring];
[self.theArray addObject:doIt];
NSLog(#"%#", self.theArray);
}
I have a problem I can't deal with.
In my application, I get datas from my Web Service in JSON. It's UTF8-encoded and when I fill an UITableView everything is ok (NSLog return accents like : "\u00e9" but my UITableView shows it like : "é").
But when I set the same data in my detailTextLabel, it doesn't convert "\u00e9" to "é" ...
Tried some tricks with encoding, but nothing convincing.
Parsing methods :
- (NSDictionary*)fetchedData:(NSData *)responseData {
NSError* error;
self.json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
return self.json;
}
-(void)executeParsingWithUrl:(NSURL*)anUrl{
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:anUrl];
NSString *authStr = [NSString stringWithFormat:#"%#:%#",[[NSUserDefaults standardUserDefaults] stringForKey:#"username_ws"], [[NSUserDefaults standardUserDefaults] stringForKey:#"password_ws"]];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [Base64 encode:authData]];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
NSError *requestError = NULL;
NSHTTPURLResponse *response = NULL;
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&requestError];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:responseData waitUntilDone:YES];
}
Recuperation :
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
JsonParsing *getJson = [[JsonParsing alloc] init];
[getJson executeParsingWithUrl: leUrl];
self.duration = [NSString stringWithFormat:#"%#",[[getJson.json objectForKey:#"objects"]valueForKey:#"libel"]];
});
Thanks in advance !
I managed it thanks to other people.
I my cell.detailTextLabel I used this :
cell.detailTextLabel.text = [NSString stringWithCString:[myText cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding];
I'm really having trouble figuring this out. I'm parsing JSON into an array asynchronously. Running NSLog on the async function prints out an array with multiple objects, which is what I want. But when I run the NSLog on the returned array in the ViewController it only prints out the last object of the array. I then run a count on it and there is, in fact, only 1 object in the array. Why is it only returning an array with one object from an array with multiple objects? Below is my code. Thanks for any input you might have.
Function performed asynchronously
- (NSArray *)locationsFromJSONFile:(NSURL *)url {
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:30.0];
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSError *error;
NSMutableDictionary *allTeams = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
if( error )
{
NSLog(#"%#", [error localizedDescription]);
}
else {
team = allTeams[#"10"];
for ( NSDictionary *teamArray in team )
{
teams = [NSArray arrayWithObjects: teamArray[#"team"], nil];
}
}
return teams;
}
ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
JSONLoader *jsonLoader = [[JSONLoader alloc] init];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"teams" withExtension:#"json"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
teams = [jsonLoader locationsFromJSONFile:url];
int i = [teams count];
NSString *string = [NSString stringWithFormat:#"%d", i];
NSLog(#"%#", string);
});
}
You need to add object to the existing array instead of reinitalizing it everytime
teams = [NSArray arrayWithObjects: teamArray[#"team"], nil];
should be
else {
team = allTeams[#"10"];
teams = [NSMutableArray array];
for ( NSDictionary *teamArray in team )
{
[teams addObject:teamArray[#"team"]];
}
Also you are sending synchronous request using this code
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
you should use the sendAsynchronous methods. Synchronous request can be terminated by the OS itself and can lead to some confusion and bugs later on
My app parses information from a Rails app using JSON. I'm looking for a way to load the JSON asynchronously, but I'm having trouble getting my code to work with examples I have found because of the complexity of my code. What do I have to do to make my JSON load asynchronously? Thanks.
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *upcomingReleaseURL = [NSURL URLWithString:#"http://obscure-lake-7450.herokuapp.com/upcoming.json"];
NSData *jsonData = [NSData dataWithContentsOfURL:upcomingReleaseURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSArray *upcomingReleasesArray = [dataDictionary objectForKey:#"upcoming_releases"];
//This is the dateFormatter we'll need to parse the release dates
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSTimeZone *est = [NSTimeZone timeZoneWithAbbreviation:#"EST"];
[dateFormatter setTimeZone:est];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"]]; //A bit of an overkill to avoid bugs on different locales
//Temp array where we'll store the unsorted bucket dates
NSMutableArray *unsortedReleaseWeek = [[NSMutableArray alloc] init];
NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];
for (NSDictionary *upcomingReleaseDictionary in upcomingReleasesArray) {
//We find the release date from the string
NSDate *releaseDate = [dateFormatter dateFromString:[upcomingReleaseDictionary objectForKey:#"release_date"]];
//We create a new date that ignores everything that is not the actual day (ignoring stuff like the time of the day)
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components =
[gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:releaseDate];
//This will represent our releases "bucket"
NSDate *bucket = [gregorian dateFromComponents:components];
//We get the existing objects in the bucket and update it with the latest addition
NSMutableArray *releasesInBucket = [tmpDict objectForKey:bucket];
if (!releasesInBucket){
releasesInBucket = [NSMutableArray array];
[unsortedReleaseWeek addObject:bucket];
}
UpcomingRelease *upcomingRelease = [UpcomingRelease upcomingReleaseWithName:[upcomingReleaseDictionary objectForKey:#"release_name"]];
upcomingRelease.release_date = [upcomingReleaseDictionary objectForKey:#"release_date"];
upcomingRelease.release_price = [upcomingReleaseDictionary objectForKey:#"release_price"];
upcomingRelease.release_colorway = [upcomingReleaseDictionary objectForKey:#"release_colorway"];
upcomingRelease.release_date = [upcomingReleaseDictionary objectForKey:#"release_date"];
upcomingRelease.thumb = [upcomingReleaseDictionary valueForKeyPath:#"thumb"];
upcomingRelease.images = [upcomingReleaseDictionary objectForKey:#"images"];
[releasesInBucket addObject:upcomingRelease];
[tmpDict setObject:releasesInBucket forKey:bucket];
}
[unsortedReleaseWeek sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate* date1 = obj1;
NSDate* date2 = obj2;
//This will sort the dates in ascending order (earlier dates first)
return [date1 compare:date2];
//Use [date2 compare:date1] if you want an descending order
}];
self.releaseWeekDictionary = [NSDictionary dictionaryWithDictionary:tmpDict];
self.releaseWeek = [NSArray arrayWithArray:unsortedReleaseWeek];
}
One simple approach is to use NSURLConnection's convenient class method sendAsynchronousRequest:queue:error.
The following code snippet is an example how to load a JSON from a server, and where the completion handler executes on a background thread which parses the JSON. It also performs all recommended error checking:
NSURL* url = [NSURL URLWithString:#"http://example.com"];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest addValue:#"application/json" forHTTPHeaderField:#"Accept"];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse* response,
NSData* data,
NSError* error)
{
if (data) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
// check status code and possibly MIME type (which shall start with "application/json"):
NSRange range = [response.MIMEType rangeOfString:#"application/json"];
if (httpResponse.statusCode == 200 /* OK */ && range.length != 0) {
NSError* error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (jsonObject) {
dispatch_async(dispatch_get_main_queue(), ^{
// self.model = jsonObject;
NSLog(#"jsonObject: %#", jsonObject);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error];
NSLog(#"ERROR: %#", error);
});
}
}
else {
// status code indicates error, or didn't receive type of data requested
NSString* desc = [[NSString alloc] initWithFormat:#"HTTP Request failed with status code: %d (%#)",
(int)(httpResponse.statusCode),
[NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]];
NSError* error = [NSError errorWithDomain:#"HTTP Request"
code:-1000
userInfo:#{NSLocalizedDescriptionKey: desc}];
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error]; // execute on main thread!
NSLog(#"ERROR: %#", error);
});
}
}
else {
// request failed - error contains info about the failure
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error]; // execute on main thread!
NSLog(#"ERROR: %#", error);
});
}
}];
Although, it appears somewhat elaborate, IMO this is a minimalistic and still naïve approach. Among other disadvantages, the main issues are:
it lacks the possibility to cancel the request, and
there is no way to handle more sophisticated authentication.
A more sophisticated approach needs to utilize NSURLConnection delegates. Usually, third party libraries do implement it in this manner, encapsulating the a NSURLConnection request and other relevant state info into a subclass of NSOperation. You may start with your own implementation, for example using this code as a template.
If you just want to get this only json data, you do not need to set up a lot of things.
use the code below. Create jsonParse method which gets a NSData Object.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://obscure-lake-7450.herokuapp.com/upcoming.json"]];
dispatch_sync(dispatch_get_main_queue(), ^{
[self jsonParse:data];
});
});
Download your data async as in this answer: Object-c/iOS :How to use ASynchronous to get a data from URL?
Then run it through the json parser.
To generically run code in a background thread you can use this method:
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Code here is run on a background thread
dispatch_async( dispatch_get_main_queue(), ^{
// Code here is run on the main thread (the UI thread) after your code above has completed so you can update UI after the JSON call has completed if you need to.
});
});
But remember that Apple does not allow you to update UI elements in a background thread. Also, they do not allow you to spawn more threads from a background thread, it must be done from the main thread.
NSString *urlstr=#"http://itunes.apple.com/in/rss/topsongs/limit=25/json";
NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:urlstr]];
[NSURLConnection sendAsynchronousRequest:request
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse* response,
NSData* data, NSError* error)
{
NSError *myError = nil;
NSDictionary *dic1 = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
if (myError ==nil) {
NSDictionary*feed =[dic1 objectForKey:#"feed"];
NSArray*arrayofentry =[feed objectForKey:#"entry"];
for(NSDictionary *dic2 in arrayofentry) {
requestReply=[dic2 objectForKey:#"title"];
[arr1 addObject:requestReply];
}
[self.table reloadData];
}
}];
Try this code:
NSURL * inkURL = [NSURL URLWithString:#"your url"];
NSURLRequest * request = [[NSURLRequest alloc]initWithURL:inkURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * response, NSData * data, NSError * error) {
NSData * jsonData = [NSData dataWithContentsOfURL:inkURL];
NSDictionary * dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.inkArray = [dataDictionary objectForKey:#"users"];
}];