Objective-C issues with dataTaskWithRequest - ios

I have recently switched from sendSynchronousRequest to dataTaskWithRequest
with sendSynchronousRequest my method was working perfectly but when I switch to dataTaskWithRequest I get the following error:
error NSURLError * domain: #"NSURLErrorDomain" - code: 4294966096 0x15ee96c0
and
myError NSError * domain: nil - code: 1684370017 0x26cce125
I don't understand why.
Here is the old code (commented out) and the new code:
/*-(NSDictionary *)GetProductionScheduleData:(NSString *)areaDescription
{
NSString *areaDescriptionWSpaceCharacters = [areaDescription stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *requestString = [NSString stringWithFormat:#"%#?areaDescription=%#",kIP,areaDescriptionWSpaceCharacters];
NSURL *JSONURL = [NSURL URLWithString:requestString];
NSURLResponse* response = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
if(data == nil)
return nil;
NSError *myError;
NSDictionary *productionSchedule = [[NSDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
return productionSchedule;
}*/
-(void)GetProductionScheduleData:(NSString *)areaDescription Completetion:(void (^) (NSMutableDictionary * result,NSError * error))completion{
NSString *areaDescriptionWSpaceCharacters = [areaDescription stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *requestString = [NSString stringWithFormat:#"%#?areaDescription=%#",kIP,areaDescriptionWSpaceCharacters];
NSURL *JSONURL = [NSURL URLWithString:requestString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSError *myError;
NSMutableDictionary *productionSchedule = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
completion(productionSchedule,myError);
}];
[dataTask resume];
}
Please Help! This was working with sendSynchronousRequest I am starting to dislike dataTaskWithRequest.

The NSURLSession code you have is correct, I confirmed with a valid URL.
You stopped checking to see if data is nil before attempting to JSON parse it. If you add that check back I bet you'll find that there is an error and data is in fact nil.
Change to:
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// handle request error
if (error) {
completion(nil, error);
return;
}
NSError *myError;
NSMutableDictionary *productionSchedule = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
completion(productionSchedule,myError);
}];
I would recommend also checking myError before attempting to set it to productionSchedule (which could also cause a crash).

Related

Got Null Value From the api in objective c

I am fetching JSON values from the API...but it showing the values as null... I checked it in the postman it's working there and I have the response...I have listed my sample code below please mention my mistakes. I'm new to this development
- (IBAction)PaymentButtonTapped:(id)sender {
[self PayuMoneyAdminValues];
}
-(void)PayuMoneyAdminValues{
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]init];
NSString *urlstring = [NSString stringWithFormat:#"%#admindatas",restSiteURLServices];
NSURL *url = [NSURL URLWithString:urlstring];
NSString *userUpdate = [NSString stringWithFormat:#"%#",restAuth];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setURL:url];
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//NSData *data1 = [NSData dataWithContentsOfURL:url];
//Apply the data to the body
[urlRequest setHTTPBody:data1];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(data!=nil){
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (parseError) {
NSLog(#"Admin data: %#",responseDictionary);
}
}
}];
[dataTask resume];
}

Trying to understand asynchronous calls

I have this method
- (NSString*) createUserWithName:(NSString*)TheName
{
NSURL *URL =someUrlthatIncludesTheName
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURL *URL = [NSURL URLWithString:url];
NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (response) {
NSError* error = nil;
NSArray *output = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
myID = [[output objectAtIndex:0] objectForKey:#"UserID"];
}
}];
[task resume];
return myID;
}
and another method
-(void)doSomethingWith: (NSString*) anID
Somewhere in my code, I call these methods subsequently, like this:
[self createUserWithName:#"John"];
[self doSomethingWith:myID];
However, due to the fact that the NSURLSession in createUserWithName: is asynchronous, doSomethingWith: is fired with myID = (null).
What is the best way to approach this problem, without necessarily falling back to deprecated synchronous NSURLConnection?
Thanks in advance
The workflow is supposed to be
- (void)createUserWithName:(NSString*)TheName
{
NSURL *URL =someUrlthatIncludesTheName
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURL *URL = [NSURL URLWithString:url];
NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (response) {
NSError* error = nil;
NSArray *output = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
myID = [[output objectAtIndex:0] objectForKey:#"UserID"];
[self doSomethingWith:myID];
}
}];
[task resume];
}
And the call is just
[self createUserWithName:#"John"];
The method doSomethingWith: is asynchronously executed in the completion block.
Alternatively use a custom completion block
- (void)createUserWithName:(NSString *)theName completion:^(NSString *identifier)completion
{
NSURL *URL =someUrlthatIncludesTheName
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURL *URL = [NSURL URLWithString:url];
NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (response) {
NSError* error = nil;
NSArray *output = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
myID = [[output objectAtIndex:0] objectForKey:#"UserID"];
completion(myID);
}
}];
[task resume];
}
and call it with
[self createUserWithName:#"John" completion:^(NSString *identifier) {
[self doSomethingWith:identifier];
}];

How to Post JSON Data in synchronously way?

How to post JSON Data in synchronously way? Can use NSURLSession or AFNetworking or other way?
Sample basic code for posting data to server using synchronous
//PASS YOUR URL HERE
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"your URL"]];
//create the Method "POST" for posting data to server
[request setHTTPMethod:#"POST"];
//Pass The String to server like below
NSString *strParameters =[NSString strin gWithFormat:#"user_email=%#&user_login=%#&user_pass=%#& last_upd_by=%#&user_registered=%#&",txtemail.text,txtuser1.text,txtpass1.text,txtuser1.text,datestr,nil];
//Print the data that what we send to server
NSLog(#"the parameters are =%#", strParameters);
//Convert the String to Data
NSData *data1 = [strParameters dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
NSLog(#"got response==%#", resSrt);
if(resSrt)
{
NSLog(#"got response");
}
else
{
NSLog(#"faield to connect");
}
In user3182143's answer, sendSynchronousRequest is deprecated in latest version iOS 9.
You can use NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSString *strResult = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
}] resume];
Here is my solution:
- (IBAction)postJSONSynchronization:(id)sender {
__block BOOL success = NO;
__block NSDictionary *jsonDic = nil;
NSURLSession *session = [NSURLSession sharedSession];
// 创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
request.HTTPMethod = #"POST"; // 请求方法
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:#13577766655 forKey:#"phoneNumber"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
request.HTTPBody = jsonData; // 请求体
NSCondition *condition = [[NSCondition alloc] init];
// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Child Thread:%#",[NSThread currentThread]);
if (!error) {
jsonDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
success = YES;
} else {
NSLog(#"%#",error);
}
[condition lock];
[condition signal];
[condition unlock];
}];
[task resume];
// 启动任务
NSLog(#"Main Thread:%#",[NSThread currentThread]);
[condition lock];
[condition wait];
[condition unlock];
NSLog(#"测试时机");
NSLog(#"josnDic:%#",jsonDic);}

Objective-C - 'sendSynchronousRequest:returningResponse:error:' is deprecated: first deprecated in iOS 9.0

-(NSArray *)deviceCheck:(NSString *)device
{
NSString *deviceRequestString = [NSString stringWithFormat:#"%#?device=%#",webservice,device];
NSURL *JSONURL = [NSURL URLWithString:deviceRequestString];
NSURLResponse* response = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
if(data == nil)
return nil;
NSError *myError;
NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
return tableArray;
}
but I keep getting this warning:
sendSynchronousRequest:returningResponse:error:' is deprecated: first deprecated in iOS 9.0 - Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h
on this line:
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
I tried changing to to the following:
NSData* data = [NSURLSession dataTaskWithRequest:request];
and
NSData* data = [NSURLSession dataTaskWithRequest:request returningResponse:&response error:nil];
both gave me errors saying:
No known class method
PLEASE HELP
With NSURLSession,your code may like this
-(void)deviceCheck:(NSString *)device Completetion:(void (^) (NSArray * result,NSError * error))completion{
NSString *deviceRequestString = [NSString stringWithFormat:#"%#?device=%#",webservice,device];
NSURL *JSONURL = [NSURL URLWithString:deviceRequestString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSURLSessionDataTask * dataTask = [
[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(data == nil) {
completion(nil,error);
return;
}
NSError *myError;
NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
completion(tableArray,myError);
}
];
[dataTask resume];
}
Then when you use it
[self deviceCheck:#"123" Completetion:^(NSArray *result, NSError *error) {
//Here use result,and check the error
}];
Note,this method is async
If you really need synch request (and you probably shouldn't have that), you can use :
+ (instancetype)dataWithContentsOfURL:(NSURL *)aURL
options:(NSDataReadingOptions)mask
error:(NSError * _Nullable *)errorPtr

Parsing JSON Within JSON in Objective-C

I'm trying to store the JSON that is within the JSON i get from the following request...
NSURL *URL = [NSURL URLWithString:#"http://www.demo.com/server/rest/login?username=admin&password=123"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(#"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(#"Response HTTP Headers:\n%#\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response Body:\n%#\n", body);
}];
[task resume];
The resulting JSON obtain from body is the following and as you can see there is a JSON within the JSON, how can I store that JSON in a NSDictionary as you can see that JSON is between quotation marks.
[
{
tag: "login",
status: true,
data:
"
{
"userID":1,
"name":"John",
"lastName":"Titor",
"username":"jtitor01",
"userEmail":"jtitor01#gmail.com",
"age":28,
}
"
}
]
What you have in reality:
Classic JSON, where inside there is a String "representing" a JSON.
So, since we can do:
NSData <=> NSString
NSArray/NSDictionary <=> JSON NSData
We just have to switch between them according to the kind of data we have.
NSArray *topLevelJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *lowLevelString = [[topLevelJSON firstObject] objectForKey:#"data"];
NSData *lowLevelData = [lowLevelString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *final = [NSJSONSerialization JSONObjectWithData:lowLevelData options:0 error:nil];
You should use this line of code
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData: data options:kNilOptions error:&errorJson];
it will help.thanks
Try this
- (void)loadDetails {
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
_allVehicleLocationsArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
[self afterCompleteDoThis];
}] resume];
}
- (void)afterCompleteDoThis {
for (NSDictionary *vehicleDict in _allVehicleLocationsArray) {
NSLog(#" PPP %#" , [vehicleDict valueForKey:#"vehicleType"]);
}
}

Resources