NSURLSession POST request return HTML webpage code - html

I am trying to submit user input to a webpage and then retrieve returned data. This webpage takes a person's name and returns his/her information from a database. I tried to make a POST request when user clicks a button then send user's input to that webpage. But when I print out returned data, it's just the html source code of that webpage, only without javaScript. How can I change/add the below function to get the person's information page? I've spent lots of time but still can't figure it out. Please help me! Thank you!
-(void) sendHTTPPost{
NSString* input = nameTextField.text;
//1
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://find.pitt.edu"]];
[req setHTTPMethod:#"POST"];
//2
NSData* postData = [input dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
//3
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[req setValue:postLength forHTTPHeaderField:#"Content-Length"];
[req setValue:#"text/html" forHTTPHeaderField:#"Content-type"];
[req setHTTPBody:postData];
//4
NSURLSession *session = [NSURLSession sharedSession];
//5
NSURLSessionDataTask *task = [session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Do something with response data here - convert to JSON, check if error exists, etc....
if(error != nil){
NSLog(#"error: %#", error);
}
else{
NSString* str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", str);
NSLog(#"response = %#", response);
}
}];
[task resume];
}

It is unlikely that the POST body is supposed to contain only the value. Chances are, it should contain
key=value&key2=value2&key3=value3...
where key is the name of the input, and value is the value of that input, in a URL-encoded format. (See "Encoding URL Data" in URL Session Programming Guide for details on how to URL-encode the values.)

Related

Objective C Find a HTML input line in NSData

I am trying to read in a website and find a input line from the code. But can't figure out how to find the a line of data.
Trying to find the line:
<input type="hidden" name="_token" value="01234abcABC">
Here is my code.
NSURL *nsurl = [NSURL URLWithString:#"https://www.mywebsite.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl];
[request setTimeoutInterval:10];
[request setHTTPMethod:#"GET"];
NSHTTPURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
if(data == nil)
return;
// Need to loop through the data line by line to find this line?
Regular expressions can be your best friends.
// Add a NUL byte so that the data is a valid C string
NSMutableData *mutableData = [data mutableCopy];
char nul = '\0';
[mutableData appendBytes:&nul length:1];
// Wrap the data as a string
NSString *dataStr = [NSString stringWithUTF8String:data.bytes];
// Find the target string within the data string
NSRange inputTagRange = [dataStr rangeOfString:
#"<input\\s+type=\"hidden\"\\s+name=\"_token\"\\s+value=\"[0-9a-zA-Z]+\">"
options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
// Expand the target range to cover each line that the target spans
NSRange inputTagLineRange = [dataStr lineRangeForRange:inputTagRange];
See it working here.

Replace NSURLConnection with NSURLSession to download and parse json feed

I'm a beginner in the area to work with database on iOS. However I could find a way to connect to a MySQL database, download and parse the json feed. Now in iOS 9, I can't use NSURLConnection anymore, that's why I have to replace it with NSURLSession. I saw many tutorials for example this here. So far, I was not able to replace it. Because I'm under time pressure, I can't waste more time to do this. Is here anyone who could help me to replace it?
My code looks exactly like this:
- (void)downloadItems
{
// Download the json file
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://myhost.ch/test.php"];
// Create the request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
// Create the NSURLConnection
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
#pragma mark NSURLConnectionDataProtocol Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// Initialize the data object
_downloadedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the newly downloaded data
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Create an array to store the locations
NSMutableArray *_locations = [[NSMutableArray alloc] init];
// Parse the JSON that came in
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];
// Loop through Json objects, create question objects and add them to our questions array
for (int i = 0; i < jsonArray.count; i++)
{
NSDictionary *jsonElement = jsonArray[i];
// Create a new location object and set its props to JsonElement properties
Location *newLocation = [[Location alloc] init];
newLocation.idS = jsonElement[#"idStatistic"];
newLocation.temp = jsonElement[#"temp"];
newLocation.hum = jsonElement[#"hum"];
newLocation.date_time = jsonElement[#"date_time"];
// Add this question to the locations array
[_locations addObject:newLocation];
}
// Ready to notify delegate that data is ready and pass back items
if (self.delegate)
{
[self.delegate itemsDownloaded:_locations];
}
}
You can try this,
{
NSURL *url = [NSURL URLWithString:#"http://myhost.ch/test.php"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest setHTTPMethod:#"POST"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:theRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Result:%#", responseDict);
}];
[task resume];
}

Objective-C Authentication

I am currently writing an iPhone application that will push a username and password to a website to retrieve the HTML source code of the page which loads. I include login information in NSString *post.
When I NSLog the _responseData instance variable in the connectionDidFinishLoading method, the console prints a long series of eight digit hexadecimal numbers which I assume are some type of address or encrypted HTML (3c21444f 43545950 45206874 6d6c2050 55424c49 4320222d 2f2f5733...).
What should I do to convert/decrypt the addresses into HTML code or otherwise retrieve the HTML code of the webpage which loads?
My ViewController conforms to the NSURLConnectionDelegate protocol and includes the following code:
#interface ViewController : UIViewController<NSURLConnectionDelegate>
{
NSMutableData *_responseData;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
NSLog(#"Received response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
NSLog(#"Received data");
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
//NSString *html=[NSString stringWithContentsOfURL:[NSURL URLWithString:#"https://grades.bsd405.org/Pinnacle/Gradebook/InternetViewer/GradeSummary.aspx?&EnrollmentId=770595&TermId=127463&ReportType=0&StudentId=114040"] encoding:NSASCIIStringEncoding error:nil];
NSLog(#"Finished loading");
//PRINT HTML:
NSLog(#"Data: %#",_responseData);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
NSLog(#"Failed to load");
}
- (IBAction)goPressed:(UIButton *)sender {
NSString *post = #"__LASTFOCUS&__EVENTTARGET&__EVENTARGUMENT&__VIEWSTATE=/wEPDwUJNTkxNzI3MDIzD2QWAmYPZBYCA
gMPZBYGAgEPZBYCAgkPZBYCAgEPZBYIAgMPFgIeB1Zpc2libGVoZAIFDxYCHwBoZAIHDxYCHwBoZAIJDxYCHgVzdH
lsZQUjdmVydGljYWwtYWxpZ246bWlkZGxlO2Rpc3BsYXk6bm9uZTtkAgMPDxYCHwBoZGQCBQ9kFghmD2QWAgINDxY
CHgVjbGFzcwUQc2luZ2xlU2Nob29sTGlzdBYCAgEPZBYCAgEPEGQPFgFmFgEQBQ5EZWZhdWx0IERvbWFpbgUIUGlu
bmFjbGVnZGQCAg9kFgICEw9kFgICAQ9kFgICAQ8QZGQWAGQCBw8PFgIeBFRleHQFIFBpbm5hY2xlIEdyYWRlIDIwM
TIgV2ludGVyIEJyZWFrZGQCCA8PFgIfAwU3Q29weXJpZ2h0IChjKSAyMDEzIEdsb2JhbFNjaG9sYXIuICBBbGwgcm
lnaHRzIHJlc2VydmVkLmRkZP/l6irI9peZfyqpKjk3fwLuEbos&__EVENTVALIDATION=/wEWBgKjnbqUCQLnksmg
AQKTpbWbDgLB5+KIBAL4xb20BAK20ZqiCel6sQLBsF1W3XHOxpgq+tJj+Rx2&ctl00$ContentPlaceHolder$Use
rname=TESTUSERNAME&ctl00$ContentPlaceHolder$Password=TESTPASSWORD&ctl00$ContentPlaceHolde
r$lstDomains=Pinnacle&ctl00$ContentPlaceHolder$LogonButton=Sign
in&PageUniqueId=2dacba26-
bb0d-412f-b06a-e02caf039c4b";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://grades.bsd405.org/Pinnacle/Gradebook/Logon.aspx?ReturnUrl=%2fPinnacle%2fGradebook%2fDefault.aspx"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection connectionWithRequest:request delegate:self];
}
The NSLog of your NSData displays the object's description, which a hexadecimal string of the underlying binary data:
3c21444f 43545950 45206874 6d6c2050 55424c49 4320222d 2f2f5733 ...
Translates to a string of
<!DOCTYPE html PUBLIC "-//W3 ...
To get the NSString from the NSData, you do:
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSURLSession in main thread

I'm attempting to download data from MySQL. However when NSURLSession creates a new thread, the data hasn't completely downloaded and thus the main thread is dealing with null values / crashes. I've used GCD's dispatch_async, however it's a few milliseconds slow.
In my test program, I have two NSLogs, one directly after calling the NSURLSession method and the other in the method itself. The output (below) shows NSURLSession is delayed by 30 milliseconds. Although while the time itself isn't much, it would have an enormous impact in how I'll structure my task. Is there any way to pause the main thread until the data has been downloaded and the method has been finished?
2014-03-30 18:56:06.224 TestProgram[1396:60b] (null)
2014-03-30 18:56:06.258 TestProgram[1396:60b] [{"error":200}]
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if(error == nil)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"%#",text);
NSError *error;
self.json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
for(int i =0 ; i < self.json.count ; i++)
{
[dataParse setDictionary:_json[i]];
}
});
} else {
NSLog(#"Response:%# %#\n", response, error);
}
}];
[dataTask resume];
Take a look at the documentation for the NSURLSessionDataTask completion routine. It seems to imply that the data is not completely downloaded at that point.

insert data to mysql fields empty

Hi im trying to insert data to a mysql database. I get new content every time i click on save but the columns in the database don't get the text (From the textview and textfields).
-(IBAction)save:(id)sender{
NSString *rawStr = [NSString stringWithFormat:#"location=%#",address.text,#"&long=%#",longitude.text,#"&lat=%#",lat.text,#"&texten=%#",texten.text];
NSData *data = [rawStr dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:#"http://url.info/projct/phpFile.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);
[self dismissViewControllerAnimated:YES completion:nil];
}
It works when i insert data to database by a webbrowser.
It does not appear that you are setting the request header to indicate that this is form-encoded data. Without this, PHP will not populate $_POST superglobal automatically (also POSTed data will not be reflected in URL). You might want to check php://input to see if you are actually getting the data:
You can do that like this:
$query_string = file_get_contents('php://input');
var_dump($query_string);