Xcode 7 Json Fetching always crashing - nsjsonserialization

Whenever I am trying to fetch data through JSon in xcode 7 it is giving me error :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
In xcode 6 it is working fine. Is new method has been implemented in xcode 7 to fetch data from json .
[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139"]];
id response=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];

NSError *error;
NSURL *url = [NSURL URLWithString:#"http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse: nil error:&error];
if (!data)
{
NSLog(#"Download Error: %#", error.localizedDescription);
}
// Parsing the JSON data received from web service into an NSDictionary object
NSDictionary *jSON =
[NSJSONSerialization JSONObjectWithData: data
options: NSJSONReadingMutableContainers
error: &error];
try this its working

In iOS 9.0 it will no more support http:// it need https://
adding this to info.plist solve the issue but don't know will apple allow such app to publish in app store .
< key>NSAppTransportSecurity< / key>
< dict>
< key>NSAllowsArbitraryLoads< / key>< true/>
< / dict>
Adding this by editing info.plist in text editor doesn't work , has to do from xcode itself. (I am a new to programming)

Related

NSMutableURLRequest get -1012 http status code instead of 401

I have to pass Authorization token in NSMutableURLRequest , My query is Whenever I have to pass Correct token than I am getting good response with https Status (200.. etc). but whenever I have to pass wrong Authorization token Than I am getting following response insted of http status code 401
* with wrong token response * (I had hide my query htpp:....)
Error Domain=NSURLErrorDomain Code=-1012 "(null)" UserInfo={NSErrorFailingURLStringKey=http......, NSUnderlyingError=0x60800024c420 {Error Domain=kCFErrorDomainCFNetwork Code=-1012 "(null)" UserInfo={_kCFURLErrorAuthFailedResponseKey={url = http.....}}}, NSErrorFailingURLKey=http....}
** here is my code **
// parameter in dictionary
NSDictionary *parameters = #{ #"user_id": [NSNumber numberWithInt:1]};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters
options:NSJSONWritingPrettyPrinted
error:&error];
// Convert dictionary to Json String
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
jsonparameter = jsonString;
}
NSData *postData = [jsonparameter dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:SiteAPIURL,wsname]]];
NSString *Accesstoken = [NSString stringWithFormat:#"Bearer %#",tokenInfo.access_token];
// Set Access token
[request setValue:Accesstoken forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSHTTPURLResponse __autoreleasing *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"%#",error.localizedDescription);
NSLog(#"Status code =%ld",(long)response.statusCode);
401 is server generated error. -1012 is system generated error. This sometimes may be because of app is keeping cached certificates and certificate on the server has been changed so they don't match. Clearing Caches and Preferences folders from app's home directory will delete the old certificate data and app will have to download the new one from the server and you problem will be solved.

.NET Web Api Token Authentication Rest Service "Get" Method in Objective-C

I'm trying to access the following URL:
http://appointmentreminder4.azurewebsites.net/Profile
This URL uses a "Get" method, and is supposed to provide JSON results. Before accessing the URL, you need to login using your Email Address and Password. After logging in successfully, the Web API issues a token. This token is used in ALL communications going forward.
I am currently unable to retrieve the token in Objective-C. I have attempted to google this problem, but I cannot figure out:
1) How to get the token
2) How to get the JSON output from the URL.
Here is the code I have written so far that returns neither the JSON, nor the token:
NSDictionary *postDict = [[NSDictionary alloc] initWithObjectsAndKeys:
#"Email Adress", #"MyEmailAddress",
#"Password", #"MyPassword",
nil];
NSError *error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:postDict options:kNilOptions error:&error];
NSURLResponse *response;
NSData *localData = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://appointmentreminder4.azurewebsites.net/home"]];
[request setHTTPMethod:#"POST"];
if (error == nil)
{
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:jsonData];
// Send the request and get the response
localData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *result = [[NSString alloc] initWithData:localData encoding:NSASCIIStringEncoding];
NSLog(#"Post result : %#", result);
}
If the above link fails, use this link to navigate to the specific page:
http://appointmentreminder4.azurewebsites.net/home

Objective C Update RESTful Webservice

I have a web service that allows me to update records on in our database.
The columns in the table are as follows:
allowsActions
assetID
inventoryObjectID
objectDescription
quantity
retired
serialNumber
action
I'm using the following to GET data from the webservice.
NSString *urlString = [NSString stringWithFormat:#"%#", inventoryAndActionsWebservice];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
Then shoving into a dictionary like so:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSLog(#"WE HAS THE DATAS");
NSDictionary *inventory = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
// Then storing the values in CoreData here
}
}
What would be the syntax for updating the webservice? It expects an object in the body of the service call (POST).
NSMutableURLRequest let's you setHTTPBody: and setHTTPMethod:.#"POST"is the way to do a post. Most services need to know the body length and encoding set in headers. (seeaddValue:forHTTPHeaderField:`) for that.
The only reason this topic is tricky is because the developer is forced to grapple with two problems at once: what constitutes a valid request for my server, and (2) how do I form that request with iOS? Part (2) is actually pretty easy once you get a valid request.
The best way to proceed is to get an example working using curl (or something equivalent). Then move on to producing that request in iOS. If you have trouble, ask a question here of the form: "I know my server needs X, here's my code to produce X, but I'm getting this error Y".
So the syntax that I was looking for was ultimately this:
NSString *jSONString = [NSString stringWithFormat:#"{\"MediaInventoryObjectsId\":%d,\"AssetId\":%d,\"Quantity\":%d,\"SerialNumber\":\"%#\",\"Description\":\"%#\",\"AllowActions\":%d,\"Retired\":%d}",inventoryObjectId, assetID, quantity, serialNumber, description, allowActions, retired];
// Convert jSON string to data
NSData *putData = [jSONString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Instantiate a url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
// Set the request url format
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/%d", inventoryAndActionsWebservice, inventoryObjectId]]];
[request setHTTPMethod:#"PUT"];
[request setHTTPBody:putData];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
// Send data to the webservice
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

Cocoa error 3840 using JSON (iOS)

I'm trying to send data to a server and receive the response in JSON format. The problem is that the server has to return "success" or "fail" but it returns "(null)".
Here's the returned error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be
completed. (Cocoa error 3840.)" (JSON text did not start with array or
object and option to allow fragments not set.) UserInfo=XXXXXXXXX
{NSDebugDescription=JSON text did not start with array or object and
option to allow fragments not set.}
Is it possible that the error is in the server script?
Here's my function to send the data and receive the response:
- (void) putData:(NSString *)parameter valor:(NSString *)valor {
NSString *rawString = [NSString stringWithFormat:#"%#=%#", parameter, valor];
NSData *data = [rawString dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:#"http://www.xxx.xxx/xxx.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"PUT"];
[request setHTTPBody:data];
NSURLResponse *response;
NSError *error;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSLog(#"responseData: %# error: %#", json, error);
}
Unless you pass the option NSJSONReadingAllowFragments to [NSJSONSerialization JSONObjectWithData:options:error:] the response from the server must be valid JSON with a top level container which is an array or dictionary.
for example:
{ "response" : "Success" }
P.S.
If you want a mutable dictionary you must also include NSJSONReadingMutableContainers in your options.
It may possible that, the response from your server doesn't contain valid JSON.
Technically, The JSON object must be start with either an "array" or an "object (dictionary)".
So, Whatever your server is returning isn't.
And, you can force the JSON to be consumed regardless by using the NSJSONReadingAllowFragments option.
by using ,
AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
You can get this issue if you're connected to VPN on your iOS device.

TOUCHJSON Serialization from NSDictionary

I've read through the questions and answers related to TouchJSON serialization and I'm still not getting it to work.
I create an NSDictionary with sample data and used the JSONTouch serializer to convert the NSDictionary to JSON. However, when I log the NSData object 'theJSONData', it gives me this as a result:
<7b223131 31353535 34343434 223a2250
...
65227d>
Additionally, when I send this 'theJSONData' data to the web service (that's expecting JSON) this is what I get back:
2011-07-31 18:48:46.572 Street Lights[7169:207] Serialization Error: (null)
2011-07-31 18:48:46.804 Street Lights[7169:207] returnData: (null)
2011-07-31 18:48:46.805 Street Lights[7169:207] Error: Error Domain=kJSONScannerErrorDomain Code=-201 "Could not scan array. Array not started by a '[' character." UserInfo=0x4d51ab0 {snippet=!HERE>!?xml version="1.0" , location=0, NSLocalizedDescription=Could not scan array. Array not started by a '[' character., character=0, line=0}
What am I doing wrong? Does the JSON NSData object 'theJSONData' need to be converted to another type before I send it to the web service? Is there another step I'm missing?
// Create the dictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
#"YCoord", #"12678967.543233",
#"XCoord", #"12678967.543233",
#"StreetLightID", #"666",
#"StreetLightCondition", #"Let's just say 'BAD'",
#"PhoneNumber", #"1115554444",
#"LastName", #"Smith",
#"Image",#"",
#"FirstName", #"Dawn",
#"Comments", #"Pole knocked down",
nil];
NSError *error = NULL;
// Serialize the data
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(#"theJSONData: %#", theJSONData);
NSLog(#"Serialization Error: %#", error);
// Set up the request and send it
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://24.52.35.127:81/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: theJSONData];
// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];
NSLog(#"returnData: %#",theObject);
NSLog(#"Error: %#", error);
Thanks for everyone's help. I ended up using Fiddler to track what needed to be sent to the service in JSON and then saw I hadn't been formatting the header correctly. Here is the code that ended up working for me.
// Create the NSDictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
#"12.543233",#"YCoord",
#"12.543233",#"XCoord",
#"111",#"StreetLightID",
#"Dented pole",#"StreetLightCondition",
#"1115554444",#"PhoneNumber",
#"Black",#"LastName",
[NSNull null],#"Image",
#"White",#"FirstName",
#"Hit by a car",#"Comments",
nil];
// Serialize the data
NSError *error = NULL;
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(#"Serialization Error: %#", error);
// Change the data back to a string
NSString* theStringObject = [[NSString alloc] initWithData:theJSONData encoding:NSUTF8StringEncoding];
// Determine the length of the data
NSData *requestData = [NSData dataWithBytes: [theStringObject UTF8String] length: [theStringObject length]];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:#"%d", [requestData length]];
// Create request to send to web service
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://11.22.33.444:55/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:requestData];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:30.0];
// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];
NSLog(#"returnData: %#",returnString);
NSLog(#"Error: %#", error);
For one thing, you've got your objects and keys reversed in the NSDictionary.
I don't know enough about TouchJSON to help with that part of the code.
I am having similar issues in parsing a goodle v3 api response. Still no closer to resolving my issue, but one thing I have found that may be helpful to you is if you are using the deserializerAsArray then the JSON response must be enclose in "[" and "]" and if you are deserializerAsDictionary then the JSON response must be enclosed in "{" and "}".
As the google v3 api JSON response is in the "{" "}" format I need to use deserialiserAsDictionary method.
I suspect you know this already, but after looking at Jonathan Wight's code this is as far as I have come in resolving my own issue as Jonathan's code is specific in checking for the above in parsing the JSON response.
Thanks,
Tim