Converting JSON Result as an Array - objective-c

I have this JSON data :
array: {
data = (
{
"com_id" = 1;
"com_name" = Apple;
},
{
"com_id" = 2;
"com_name" = "Google";
},
{
"com_id" = 3;
"com_name" = "Yahoo";
}
);
message = "Data found";
response = success;
}
here's my code to fetch that data :
NSURL * url = [[NSURL alloc] initWithString:#"https://jsonurlhere.com"];
// Prepare the request object
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Prepare the variables for the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
// Construct a Array around the Data from the response
NSArray* object = [NSJSONSerialization
JSONObjectWithData:urlData
options:0
error:&error];
NSLog(#"array: %#", object);
now, I want to use that JSON data into my PickerView. how to change that JSON data into array so that I can load it to replace my existing array (self.nameCompany)?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.nameCompany = #[#"Apple", #"Google", #"Yahoo"];
}

I think It's helpful to you. Can you try this following link? It's not use to any supporting files. Also, see this link NSJSONSerialization supported URL
NSJSONSerialization

check this code , your response is not a array but Dictionary.
-(void)loadData{
NSURL * url = [[NSURL alloc] initWithString:#"https://jsonurlhere.com"];
// Prepare the request object
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Prepare the variables for the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
// Construct a Array around the Data from the response
NSDictionary* object = [NSJSONSerialization
JSONObjectWithData:urlData
options:0
error:&error];
NSLog(#"array: %#", [object objectForKey:#"data"]);
NSMutableArray *companyArray=[[NSMutableArray alloc] init];
for (NSDictionary *tempDict in [object objectForKey:#"data"]) {
[companyArray addObject:[tempDict objectForKey:#"com_name"]];
}
self.nameCompany=[NSArray arrayWithArray:companyArray];
}

Related

Trouble Storing URL in NSURL Variable

At the end of this method, "address" (NSURL variable) returns nil, even though "countyName" returns #"Alameda". What am I doing wrong?
-(void) getDataUrl {
if ([countyName isEqual: #"Alameda"]) {
NSURL * fileURL = [[NSURL alloc] initWithString:#"http://www.myservername.com/alameda.php"];
self.address = fileURL;
}
if ([countyName isEqual: #"Napa"]) {
NSURL * fileURL = [[NSURL alloc] initWithString:#"http://www.myservername.com/napa.php"];
self.address = fileURL;
}
if ([countyName isEqual: #"San Luis Obispo"]) {
NSURL * fileURL = [[NSURL alloc] initWithString:#"http://www.myservername.com/sanluisobispo.php"];
self.address = fileURL;
}
}
The solution here was to create a plist containing an array of dictionaries. Each dictionary held the name of a county and a url for the php script for that county. The plist was used to populate a tableview, and then the selected row was pushed to another tableview using the variable "countyName". "countyName" held the county name and the url. I then used countyName in my retrieveData method like this:
NSURL *url = [NSURL URLWithString:[countyName valueForKey:#"weburl"]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
Thanks to everyone for taking the time to respond.

How to pass an HTTP as a header in with NSURLSession

I'm trying to submit a GET request from a web service and I want to pass a JSON argument as a parameter in the HTTP header. I have the following code that performs the get request without the JSON argument. How would I add the JSON argument in the HTTP body to pass the JSON parameter?
Heres is my code that works without the JSON argument:
-(void) getReposByDate:(void (^)(NSMutableArray *))handler
{
//Get credentials
NSDictionary *credentials = [KeychainUserPass load:#"APP NAME"];
NSString *userName = [credentials allKeys][0];
NSString *password = credentials[userName];
//Create request
NSString *requestString = #"SOME WEB SERVICE URL";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSData *userPasswordData = [[NSString stringWithFormat:#"%#:%#", userName, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:#"Basic %#", base64EncodedCredential];
NSURLSessionConfiguration *sessionConfig=[NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.HTTPAdditionalHeaders=#{#"Authorization":authString};
self.session=[NSURLSession sessionWithConfiguration:sessionConfig];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"%#", jsonObject);
handler([jsonObject valueForKeyPath:#"name"]);
}];
[dataTask resume];
}

JSON to Objective-C Dictionary

I'm making URL Request to an API but I dont know how to render the JSON, It generates an array of multiple users like this [{"user": "value"}, {"user":"value"}] and I was trying to use a TableView so I need an NSDictionary but i think is better to render a JSON like {users: [{"user": "value"}, {"user":"value"}]}. I have this code to make the request
#import "JSONKit.h"
NSError *error = nil;
NSURLResponse *response = nil;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://localhost:3000/getusers"]];
[request setHTTPMethod:#"GET"];
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
users = [[jsonData objectFromJSONData] objectForKey:#"users"];
usersKeys = [users allKeys];
but I'm getting this error
2012-09-16 18:51:11.360 tableview[2979:c07] -[JKArray allKeys]: unrecognized selector sent to instance 0x6d30180
2012-09-16 18:51:11.362 tableview[2979:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[JKArray allKeys]: unrecognized selector sent to instance 0x6d30180'
I dont really know how to accomplish this so any help is useful, thanks
You are getting that error because whatever got parsed out of "jsonData" isn't necessarily what you expected (i.e. a dictionary).
Perhaps you need some error checking in that code of yours.
For example:
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if(jsonData)
{
id objectReturnedFromJSON = [jsonData objectFromJSONData];
if(objectReturnedFromJSON)
{
if([objectReturnedFromJSON isKindOfClass:[NSDictonary class]])
{
NSDictionary * dictionaryFromJSON = (NSDictionary *)objectReturnedFromJSON;
// assuming you declared "users" & "usersKeys" in your interface,
// or somewhere else in this method
users = [dictionaryFromJSON objectForKey:#"users"];
if(users)
{
usersKeys = [users allKeys];
} else {
NSLog( #"no users in the json data");
}
} else {
NSLog( #"no dictionary from the data returned by the server... check the data to see if it's valid JSON");
}
} else {
NSLog( #"nothing valid returned from the server...");
}
} else {
NSLog( #"no data back from the server");
}
I was thinking on something like this
NSError *error = nil;
NSURLResponse *response = nil;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://localhost:3000/getusers"]];
[request setHTTPMethod:#"GET"];
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
JSONDecoder *decoder = [[JSONDecoder alloc]
initWithParseOptions:JKParseOptionNone];
NSArray *json = [decoder objectWithData:jsonData];
NSMutableArray *objects = [[NSMutableArray alloc] init];
NSMutableArray *keys = [[NSMutableArray alloc] init];
for (NSDictionary *user in json) {
[objects addObject:[user objectForKey:#"user" ]];
[keys addObject:[user objectForKey:#"value" ]];
}
users = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
NSLog(#"users: %#", users);
usersKeys = [users allKeys];
But it doesnt look efficient for many items or im wrong?

Getting external XML with GDataXMLNode for Objective-C?

I am working on a method to communicate between my PHP api and a iOS application. This is the reason why i wrote a function wich will get an external XML feed(of my api) and parse it.
But in the process to do that, i found a problem. The next code i wrote won't work:
-(void)getXML:(NSURL *)url {
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
NSURLResponse *resp = nil;
NSError *err = nil;
NSData *response = [NSURLConnection sendSynchronousRequest: theRequest returningResponse: &resp error: &err];
xmlDocument = [[GDataXMLDocument alloc]initWithData:response options:0 error:&error];
NSArray *data = [[xmlDocument rootElement]elementsForName:#"api"];
data_from_xml = [[NSMutableArray alloc]init];
for(GDataXMLElement *e in data)
{
[data_from_xml addObject:e];
}
NSLog(#"xmlDocument:%#]\n\nData:%#\n\nData_from_xml:%#\n\nURL:%#", xmlDocument,data,data_from_xml, url);
}
The log returns:
xmlDocument:GDataXMLDocument 0x5a1afb0
Data:(null)
Data_from_xml:(
)
URL:http://sr.site-project.nl/api/?t=store.search.keyword
So, it seems that GDataXMLDocument has the XML. But i can't load it with the elementsForName argument?.
Does someone see what the problem is?
The XML:
<?xml version="1.0"?>
<api><type>core.error</type><errorMessage>API store.search.keyword doesn't exists</errorMessage></api>
The api node is your root element:
NSArray *data = [[xmlDocument rootElement]elementsForName:#"api"];
Try:
NSError *error = nil;
NSArray *data = [xmlDocument nodesForXPath:#"//api" error:&error];
I personally prefer the nodesForXPath method for retrieving elements.

Simple http post example in Objective-C?

I have a php webpage that requires a login (userid & password). I have the user enter the information into the app just fine.. but I need an example on how to do a POST request to a website. The apple example on the support site is rather complicated showing a picture upload.. mine should be simpler.. I just want to post 2 lines of text..
Anyone have any good examples?
Alex
This is what I recently used, and it worked fine for me:
NSString *post = #"key1=val1&key2=val2";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http://www.nowhere.com/sendFormHere.php"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
Originally taken from http://deusty.blogspot.com/2006/11/sending-http-get-and-post-from-cocoa.html, but that blog does not seem to exist anymore.
From Apple's Official Website :
// In body data for the 'application/x-www-form-urlencoded' content type,
// form fields are separated by an ampersand. Note the absence of a
// leading ampersand.
NSString *bodyData = #"name=Jane+Doe&address=123+Main+St";
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://www.apple.com"]];
// Set the request's content type to application/x-www-form-urlencoded
[postRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
// Designate the request a POST request and specify its body data
[postRequest setHTTPMethod:#"POST"];
[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];
// Initialize the NSURLConnection and proceed as described in
// Retrieving the Contents of a URL
From : code with chris
// Create the request.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com"]];
// Specify that it will be a POST request
request.HTTPMethod = #"POST";
// This is how we set header fields
[request setValue:#"application/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
// Convert your data and set your request's HTTPBody property
NSString *stringData = #"some data";
NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
ASIHTTPRequest makes network communication really easy
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addPostValue:#"Ben" forKey:#"names"];
[request addPostValue:#"George" forKey:#"names"];
[request addFile:#"/Users/ben/Desktop/ben.jpg" forKey:#"photos"];
[request addData:imageData withFileName:#"george.jpg" andContentType:#"image/jpeg" forKey:#"photos"];
You can do using two options:
Using NSURLConnection:
NSURL* URL = [NSURL URLWithString:#"http://www.example.com/path"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
// Form URL-Encoded Body
NSDictionary* bodyParameters = #{
#"username": #"reallyrambody",
#"password": #"123456"
};
request.HTTPBody = [NSStringFromQueryParameters(bodyParameters) dataUsingEncoding:NSUTF8StringEncoding];
// Connection
NSURLConnection* connection = [NSURLConnection connectionWithRequest:request delegate:nil];
[connection start];
/*
* Utils: Add this section before your class implementation
*/
/**
This creates a new query parameters string from the given NSDictionary. For
example, if the input is #{#"day":#"Tuesday", #"month":#"January"}, the output
string will be #"day=Tuesday&month=January".
#param queryParameters The input dictionary.
#return The created parameters string.
*/
static NSString* NSStringFromQueryParameters(NSDictionary* queryParameters)
{
NSMutableArray* parts = [NSMutableArray array];
[queryParameters enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
NSString *part = [NSString stringWithFormat: #"%#=%#",
[key stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding],
[value stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]
];
[parts addObject:part];
}];
return [parts componentsJoinedByString: #"&"];
}
/**
Creates a new URL by adding the given query parameters.
#param URL The input URL.
#param queryParameters The query parameter dictionary to add.
#return A new NSURL.
*/
static NSURL* NSURLByAppendingQueryParameters(NSURL* URL, NSDictionary* queryParameters)
{
NSString* URLString = [NSString stringWithFormat:#"%#?%#",
[URL absoluteString],
NSStringFromQueryParameters(queryParameters)
];
return [NSURL URLWithString:URLString];
}
Using NSURLSession
- (void)sendRequest:(id)sender
{
/* Configure session, choose between:
* defaultSessionConfiguration
* ephemeralSessionConfiguration
* backgroundSessionConfigurationWithIdentifier:
And set session-wide properties, such as: HTTPAdditionalHeaders,
HTTPCookieAcceptPolicy, requestCachePolicy or timeoutIntervalForRequest.
*/
NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
/* Create session, and optionally set a NSURLSessionDelegate. */
NSURLSession* session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:nil];
/* Create the Request:
Token Duplicate (POST http://www.example.com/path)
*/
NSURL* URL = [NSURL URLWithString:#"http://www.example.com/path"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
// Form URL-Encoded Body
NSDictionary* bodyParameters = #{
#"username": #"reallyram",
#"password": #"123456"
};
request.HTTPBody = [NSStringFromQueryParameters(bodyParameters) dataUsingEncoding:NSUTF8StringEncoding];
/* Start a new Task */
NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error == nil) {
// Success
NSLog(#"URL Session Task Succeeded: HTTP %ld", ((NSHTTPURLResponse*)response).statusCode);
}
else {
// Failure
NSLog(#"URL Session Task Failed: %#", [error localizedDescription]);
}
}];
[task resume];
}
/*
* Utils: Add this section before your class implementation
*/
/**
This creates a new query parameters string from the given NSDictionary. For
example, if the input is #{#"day":#"Tuesday", #"month":#"January"}, the output
string will be #"day=Tuesday&month=January".
#param queryParameters The input dictionary.
#return The created parameters string.
*/
static NSString* NSStringFromQueryParameters(NSDictionary* queryParameters)
{
NSMutableArray* parts = [NSMutableArray array];
[queryParameters enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
NSString *part = [NSString stringWithFormat: #"%#=%#",
[key stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding],
[value stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]
];
[parts addObject:part];
}];
return [parts componentsJoinedByString: #"&"];
}
/**
Creates a new URL by adding the given query parameters.
#param URL The input URL.
#param queryParameters The query parameter dictionary to add.
#return A new NSURL.
*/
static NSURL* NSURLByAppendingQueryParameters(NSURL* URL, NSDictionary* queryParameters)
{
NSString* URLString = [NSString stringWithFormat:#"%#?%#",
[URL absoluteString],
NSStringFromQueryParameters(queryParameters)
];
return [NSURL URLWithString:URLString];
}
I am a beginner in iPhone apps and I still have an issue although I followed the above advices. It looks like POST variables are not received by my server - not sure if it comes from php or objective-c code ...
the objective-c part (coded following Chris' protocol methodo)
// Create the request.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://example.php"]];
// Specify that it will be a POST request
request.HTTPMethod = #"POST";
// This is how we set header fields
[request setValue:#"application/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
// Convert your data and set your request's HTTPBody property
NSString *stringData = [NSString stringWithFormat:#"user_name=%#&password=%#", self.userNameField.text , self.passwordTextField.text];
NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
// Create url connection and fire request
//NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSData *response = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil error:nil];
NSLog(#"Response: %#",[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]);
Below the php part :
if (isset($_POST['user_name'],$_POST['password']))
{
// Create connection
$con2=mysqli_connect($servername, $username, $password, $dbname);
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
// retrieve POST vars
$username = $_POST['user_name'];
$password = $_POST['password'];
$sql = "INSERT INTO myTable (user_name, password) VALUES ('$username', '$password')";
$retval = mysqli_query( $sql, $con2 );
if(! $retval )
{
die('Could not enter data: ' . mysql_error());
}
echo "Entered data successfully\n";
mysqli_close($con2);
}
}
else
{
echo "No data input in php";
}
I have been stuck the last days on this one.
NSMutableDictionary *contentDictionary = [[NSMutableDictionary alloc]init];
[contentDictionary setValue:#"name" forKey:#"email"];
[contentDictionary setValue:#"name" forKey:#"username"];
[contentDictionary setValue:#"name" forKey:#"password"];
[contentDictionary setValue:#"name" forKey:#"firstName"];
[contentDictionary setValue:#"name" forKey:#"lastName"];
NSData *data = [NSJSONSerialization dataWithJSONObject:contentDictionary options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"%#",jsonStr);
NSString *urlString = [NSString stringWithFormat:#"http://testgcride.com:8081/v1/users"];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"moinsam" password:#"cheese"];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:<block> failure:<block>];
Thanks a lot it worked , please note I did a typo in php as it should be mysqli_query( $con2, $sql )
Here i'm adding sample code for http post print response and parsing as JSON if possible, it will handle everything async so your GUI will be refreshing just fine and will not freeze at all - which is important to notice.
//POST DATA
NSString *theBody = [NSString stringWithFormat:#"parameter=%#",YOUR_VAR_HERE];
NSData *bodyData = [theBody dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
//URL CONFIG
NSString *serverURL = #"https://your-website-here.com";
NSString *downloadUrl = [NSString stringWithFormat:#"%#/your-friendly-url-here/json",serverURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: downloadUrl]];
//POST DATA SETUP
[request setHTTPMethod:#"POST"];
[request setHTTPBody:bodyData];
//DEBUG MESSAGE
NSLog(#"Trying to call ws %#",downloadUrl);
//EXEC CALL
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"Download Error:%#",error.description);
}
if (data) {
//
// THIS CODE IS FOR PRINTING THE RESPONSE
//
NSString *returnString = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(#"Response:%#",returnString);
//PARSE JSON RESPONSE
NSDictionary *json_response = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
if ( json_response ) {
if ( [json_response isKindOfClass:[NSDictionary class]] ) {
// do dictionary things
for ( NSString *key in [json_response allKeys] ) {
NSLog(#"%#: %#", key, json_response[key]);
}
}
else if ( [json_response isKindOfClass:[NSArray class]] ) {
NSLog(#"%#",json_response);
}
}
else {
NSLog(#"Error serializing JSON: %#", error);
NSLog(#"RAW RESPONSE: %#",data);
NSString *returnString2 = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(#"Response:%#",returnString2);
}
}
}];
Hope this helps!