I'm trying to receive a correct response from a NSURL POST request in Objective-C.
My script uses PHP to send tyre sizes (4 parameters) which the user has inputted using textfields, (and then presses Submit - IB Action Button1), and then the idea is to output
the response (Quantity in stock) via the self.instock.text label.
However, ResponseData is only showing up on the console as <5b5d>.
I have already inserted rows in the MySQL database to match the test data from the App, so that's not the problem.
Can anyone see why I only receive this response?
Many, many thanks in advance!!
#import "GetQuoteViewController.h"
#interface GetQuoteViewController ()
#end
#implementation GetQuoteViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"You entered %#",self.tyrewidth.text);
[self.tyrewidth resignFirstResponder];
NSLog(#"You entered %#",self.tyreprofile.text);
[self.tyreprofile resignFirstResponder];
NSLog(#"You entered %#",self.wheelsize.text);
[self.wheelsize resignFirstResponder];
NSLog(#"You entered %#",self.speedrating.text);
[self.speedrating resignFirstResponder];
return YES;
}
- (IBAction)Button1:(id)sender {
NSString *meme = _tyrewidth.text;
NSString *meme1 = _tyreprofile.text;
NSString *meme2 = _wheelsize.text;
NSString *meme3 = _speedrating.text;
_displayMeme.text = [NSString stringWithFormat:#"%# %# %# %#",meme,meme1,meme2,meme3];
NSString *rawStr = [NSString stringWithFormat:#"tyrewidth=%#&tyreprofile=%#&wheelsize=%#&speedrating=%#", _tyrewidth.text, _tyreprofile.text, _wheelsize.text, _speedrating.text];
NSData *data = [rawStr dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:#"http://budget-tyresofhull.com/service2.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:data];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(#"responseData: %#", responseData);
NSString *responseString = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSString *name = responseString;
self.instock.text = name;
}
#end
Related
I write array in plist from json url .
I want when not exist internet tableview get data from plist and when exist tableView get data from json url
this is my code (I create plist file in Document folder application) :
#import "ViewController.h"
#define DOC_DIR [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
#implementation ViewController
{
NSMutableArray *name;
NSMutableData *data;
NSString *listPath;
NSMutableArray *array;
NSArray *n;
NSMutableArray *add;
}
#synthesize table;
-(NSString*)Dir
{
return [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)objectAtIndex:0];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://myDomain.com/test.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[con start];
}
- (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;
name = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
for (int i = 0; i < [name count]; i++) {
NSIndexPath *indexPath = [self.table indexPathForSelectedRow];
n = [[name objectAtIndex:(indexPath.row)+i]objectForKey:#"title"];
if(!add){
add = [NSMutableArray array];
}
[add addObject:n];
}
NSLog(#"add = %#",add);
[table reloadData];
[self WriteToPlist:add];
}
- (void)WriteToPlist:(NSArray*)dataArray
{
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:dataArray,#"Name", nil];
NSString *Path = [DOC_DIR stringByAppendingPathComponent:#"Plist.plist"];
[dic writeToFile:Path atomically:YES];
NSLog(#"Path : %#",Path);
}
and this code read data from json :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [name count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[name objectAtIndex:indexPath.row] objectForKey:#"title"];
//top code read data from json and I want when no internet read data from plist
return cell;
}
// Path to the plist (in the application bundle)
NSString *path = [[NSBundle mainBundle] pathForResource:
#"Plist" ofType:#"plist"];
// Build the array from the plist
NSMutableArray *array2 = [[NSMutableArray alloc] initWithContentsOfFile:path];
// Show the string values
for (NSString *str in array2)
NSLog(#"--%#", str);
You have array and now just set the value to datasource array
[tableview reloadData];
For checking the internet connectivity you can use the Reachability class provided by apple
Step 1 : Check Whether Internet is Connected OR Not using Following method, Implement this method
- (BOOL) connectedToInternet
{
NSURL *requestURL = [NSURL URLWithString:#"http://www.google.com"];
NSData *data = [NSData dataWithContentsOfURL:requestURL];
return ([data bytes]>0) ? YES : NO;
}
OR
Step 1 : You can also Implement Reachability Class to check Internet Connectivity by Apple if you Know it.
Step 2 : Now Make check for Connectivity In your Method Befor invoking Webservice Request
if([self connectedToInternet])
{
// Make a reqeust to server
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://yourDomain.com/test.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[con start];
}
else
{
// Write a Handy code to load Data from Your Local Plist
// Path to plist From Documents Folder
NSString *docFilePath = [DOC_DIR stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *dictData = [NSDictionary dictionaryWithContentsOfFile:docFilePath];
NSLog(#"%#",dictData);
// Reload your TableView
}
I want to test async HTTP get action.
#interface Sender : NSObject<NSURLConnectionDataDelegate, NSURLConnectionDelegate>
{
NSMutableData *buffer;
NSString *_html
}
- (void)getHtml;
#end
#implementation Sender
- (void)getHtml
{
NSString *urlstr = #"http://www.yahoo.co.jp";
NSURL *url = [NSURL URLWithString:urlstr];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
if (conn) {
buffer = [NSMutableData data];
} else {
// error handling
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[buffer appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeed!! Received %d bytes of data", [buffer length]);
_html = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
NSLog(#"%#", _html);
}
#end
I have to let _html property ?
#import "SenderTestCase.h"
#import "Sender.h"
#implementation SenderTestCase
- (void)setUpClass
{
sender = [[Sender alloc] init];
}
- (void)testGetHtml
{
[self prepare];
[sender getHtml];
[self performSelector:#selector(_succeedGetHtml) withObject:nil afterDelay:3.0];
[self waitForStatus:kGHUnitWaitStatusSuccess timeout:4.0];
}
- (void)_succeedGetHtml
{
if (sender.html != nil) {
[self notify:kGHUnitWaitStatusSuccess forSelector:#selector(testGetHtml)];
};
}
#end
If there is more nice way, please tell me.
Thank you for your kindness.
You are doing it correct.
If you want your code to be nicer (and shorter), consider using AFNetworking and the use of blocks.
I have a GHUnit async test example, which shows nicely within 1 method.
i'm trying to fill my UITableView with this JSON data using the ASIhttprequest, but ik get the following exception: __NSArrayM objectForKey:]: unrecognized selector sent to instance
I use the following code in my controller to achieve this:
#import <UIKit/UIKit.h>
#interface tableListViewController : UITableViewController {
NSDictionary *data;
}
#end
And the main file:
#import "tableListViewController.h"
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#interface tableListViewController ()
#end
#implementation tableListViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"http://api.glennzo.nl/glow/index.json"];
ASIHTTPRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setTag:100];
[request setDelegate:self];
[request startSynchronous];
//Set the title
self.navigationItem.title = #"Events";
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void) requestFinished:(ASIHTTPRequest *) request
{
if (request.tag == 100) {
NSData *responseData = [request responseData];
NSError *error;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if(!JSON || ![JSON count])
{
NSLog(#"%#", #"geen correcte json data van request gekregen");
}
else
{
data = JSON;
}
}
}
- (void) requestFailed:(ASIHTTPRequest *) request
{
NSError *error = [request error];
NSLog(#"Error: %#",error.localizedDescription);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [UITableViewCell alloc];
}
NSArray *namen = [data objectForKey:#"name"];
cell.textLabel.text = [namen objectAtIndex:indexPath.row];
return cell;
}
Thanks to some debugging i now know that the ASIHttpRequest works, but the NSdictionary that i create (and intent to use around the entire app) gives me the trouble. Can somebody set me in the right direction?
The error seems to be at:
NSArray *namen = [data objectForKey:#"name"];
So I think data type isn't correct (NSDictionary), is nil or it is filled with another type:
[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
Try seeing what arrives to you via JSON. For example:
NSError *jsonError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"its an array!");
NSArray *jsonArray = (NSArray *)jsonObject;
NSLog(#"jsonArray - %#",jsonArray);
} else {
NSLog(#"its probably a dictionary");
NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
NSLog(#"jsonDictionary - %#",jsonDictionary);
}
This is my first time on this site and I am very new to coding so I was wondering if somebody could help me out.
I want to set a get request from my iphone app to my website and get the information echoed back from the website to my phone.
I have gotten this far but do not know where to go from here. Any help would be much appreciated, thanks!
- (void)myData:(id)sender
{
NSString *DataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData = [[NSMutableData alloc] init];
DataToBeSent = [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[request setHTTPMethod: #"GET"];
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
[dataToBeSent release];
}
OLD WAY
- (void)myData:(id)sender
{
NSString *dataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData= [[NSMutableData alloc] init];
dataToBeSent= [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
Theconn= [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
[dataToBeSent release];
}
Then the following methods are called and I get my data BUT if I sent another request after my first one but different data on the same connection, it would always give me the same result which shouldn't happen
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
/* appends the new data to the received data */
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *stringData= [[NSString alloc]
initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Got data? %#", stringData);
[self displayAlertCode:stringData];
[stringData release];
// Do unbelievably cool stuff here //
}
Assuming your data loaded properly you can convert the data into a string and do whatever you want with it.
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
//Make sure to set the correct encoding
NSString* responseString = [[NSString alloc] initWithData:response1 encoding:NSASCIIStringEncoding];
If your server returns JSON there are 3rd party libraries that can parse the string into collections like NSArray and NSDictionary. If your server returns XML then NSXMLParser could be something you can use.
EDIT
I've changed your code to manage the memory a little differently.
.h
#property (nonatomic,retain) NSMutableData * receivedData;
#property (nonatomic,retain) NSURLConnection * Theconn;
.m
#synthesize receivedData;
#synthesize Theconn;
//A bunch of cool stuff
- (void)myData:(id)sender
{
//If you already have a connection running stop the existing one
if(self.Theconn != nil){
[self.Theconn cancel];
}
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
//This will release your old receivedData and give you a new one
self.receivedData = [[[NSMutableData alloc] init] autorelease];
NSString *dataToBeSent = [NSString stringWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php? Data=%#",sender];
NSURLRequest *theRequest= [NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
//This will release your old NSURLConnection and give you a new one
self.Theconn = [NSURLConnection connectionWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
}
//...
//Your delegate methods
//...
- (void) dealloc{
[receivedData release];
[Theconn release];
[super dealloc];
}
following code uses ASIhttprequest to fill appData array. View also includes a tableview and when is launched, getData function is executed first but then I would like to wait until request ends and appData is filled before execute tableView init methods. Now tableView methods are executed before request ends. How to do that? Thank you.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
NSArray *datos = [[NSArray alloc] initWithObjects:(#"test"), nil];
self.appData = datos;
[datos release];
}
[self getData];
return self;
}
- (void)getData
{
activityIndicator.hidden = NO;
[activityIndicator startAnimating];
NSURL *url = [NSURL URLWithString:#"http://test.com/iphone.php"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSLog(#"URL = %#",url);
[request setValidatesSecureCertificate:NO];
[request setRequestMethod:#"POST"];
[request setPostValue:#"admin" forKey:#"key1"];
[request setPostValue:#"admin" forKey:#"key1"];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(#"%#", [request responseString]);
//NSLog(#"Response %d ==> %#", request.responseStatusCode, [request responseString]);
[activityIndicator stopAnimating];
activityIndicator.hidden = YES;
appData = [[request responseString] componentsSeparatedByString: #"#"];
int x =0;
while (x<[appData count] - 1)
{
NSLog(#"cells = %#",[appData objectAtIndex: x]);
x = x+1;
}
}
You have two options here:
you alloc and init your tableview AFTER the request did finished - this is not possible if you used IB to create your tableview
you return 0 in your UITableViewDelegates - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method until the request is not finished. Then, reload the table and return the actual record count.