Within my application, I am trying to post the gps coordinates of a users position to a server for storage so that I can eventually design a map that displays all the users locations. I am using HTTP get and a custom PHP API to handle the data passing from app to db. The problem I have is, every time didUpdateLocations is called, I update the server. It works sometimes, but then sometimes my query string says there is an undefined variable and blank data is being posted int he db. Why is sometimes it undefined, and sometimes not? Also, is there a better way to handle the data passing? I was going to use ASIHTTPRequest but I am using ARC and so that is no help to me.
Code:
- (void)postLocationUpdateFor:(NSString *)deviceToken withDeviceID:(NSString*)deviceID withLatitude:(NSString *)latitude andLongitude:(NSString *)longitude {
NSString *apiURL = [NSString stringWithFormat:ServerApiURL2, deviceToken, deviceID, latitude, longitude];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:apiURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%#", strResult);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *currentLocation = [locations lastObject];
NSString *deviceToken = [[NSUserDefaults standardUserDefaults] stringForKey:#"deviceToken"];
NSString *latitude = [NSString localizedStringWithFormat:#"%f",currentLocation.coordinate.latitude];
NSString *longitude = [NSString localizedStringWithFormat:#"%f",currentLocation.coordinate.longitude];
NSLog(#"Entered new Location with the coordinates Latitude: %# Longitude: %#", latitude, longitude);
[self postLocationUpdateFor:#"123" withDeviceID:deviceToken withLatitude:latitude andLongitude:longitude];
}
didUpdateLocations
can be called when you actually lost your location: entered into an Elevator / building. That's why is sometimes empty.
I would check and validate that location values before I will send the server.
Related
I am trying to pass a date from Xcode to a PHP page (stores the Date to a mysql DB) however NSData doesn't seem to like the format of the Date.
//Format date for mysql & PHP
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *strToday = [dateFormatter stringFromDate:[NSDate date]];
NSString *strURL = [NSString stringWithFormat:#"http://www.TESTSERVER.com/Items.php?uID=123456789&item1=30&item2=5&startDate=%#&endDate=%#", strToday, strToday];
//strURL=[strURL stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"%#", strURL);
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%#", strResult);
I have tested the PHP page by entering data manually and it works without any issues. However when I ran the code above it doesn't work, I've isolated the issue to the date and I believe that NSData has a problem with the space in my Date Format (between the Date and Time).
I tried filling the gap with %20 (URL encoding etc.) and the connection is made to the db but the date field is not in the right format so it appears as null in the mysql database.
I'd rather not start parsing strings in my PHP, does anyone know how to fix this?
Below is my PHP code: -
<?PHP
$hostname = "XXX";
$username = "XXX";
$password = "XXX";
$database = "XXX";
$db_handle = mysql_connect($hostname, $username, $password);
$db_found = mysql_select_db($database, $db_handle);
$uID = $_GET['uID'];
$item1 =$_GET['item1'];
$item2 =$_GET['item2'];
$startDate =$_GET['startDate'];
$endDate =$_GET['endDate'];
if ($db_found) {
$sql = "INSERT INTO Items (uID, item1, item2, startDate, endDate) VALUES ('$uID','$item1','$item2','$startDate','$endDate');";
//$cleanSQL = str_replace("%20"," ",$sql);
$result = mysql_query($sql);
mysql_close($db_handle);
print "Records added to the database";
} else {
print "Database NOT Found ";
mysql_close($db_handle);
}
?>
There's a many problems with this code, but it's impossible to diagnose what precisely is causing the problem you describe on the basis of the limited information provided. A few observations:
You definitely need to percent escape the date string. The space is not acceptable in a URL (nor the body of a standard x-www-form-urlencoded request).
If you are inserting data, you should be issuing POST request, not adding this stuff to a URL, in effect issuing GET request.
You should not be issuing request with dataWithContentsOfURL. Not only is that GET, but it's synchronous and doesn't report the error.
If you still have problems, you should observe this request with Charles or similar tool. Observe the same request that you have working via web browser and compare and contrast.
Personally, when I have problems, I temporarily change my PHP code to return the data I passed to it, so I can make sure that everything was received correctly. It's a simple, but effective, way to confirm that everything was received properly.
If you are passing date strings to the server, you generally should use GMT timezone, to avoid problems stemming from the server not knowing what time zone the user's device is located. Likewise, you should use en_US_POSIX locale, to avoid problems with non-gregorian calendars. See Apple Technical Q&A 1480.
Pulling that all together, you end up with something more like:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; // if you REALLY want to use local timezone, eliminate this line, but I'd really advise sticking with GMT when using formatters to create and parse date strings that you're sending to a remote server
NSString *strToday = [dateFormatter stringFromDate:[NSDate date]];
NSURL *url = [NSURL URLWithString:#"http://www.TESTSERVER.com/Items.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *body = [[NSString stringWithFormat:#"uID=123456789&item1=30&item2=5&startDate=%#&endDate=%#", strToday, strToday] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"]; // not necessary, but good practice
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// use the data/error/response objects here
if (data) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString = %#", responseString);
} else {
NSLog(#"error = %#", error);
NSLog(#"response = %#", response);
}
}];
[task resume];
// don't try to use the string here, because the above happens asynchronously
Frankly, I don't like this overly simplistic mechanism of setting the body (if any of the fields included special characters like + or &, the above wouldn't work). But if the parameters are precisely as you've outlined them in your question, this simplistic solution should work. But, if you want something a little more robust in this regard, see the encodePostParameters method shown in https://stackoverflow.com/a/22887238/1271826.
By the way, I'd suggest considering using AFNetworking, as that gets you out of the weeds of manually constructing requests.
But, going back to your original question, we cannot advise you further without seeing the server code or you doing more debugging (Charles, confirming that the values are correctly being received, etc.).
I receive a funnily formatted $_POST submission in a php script being sent in the form:
{"receipt-data":"MILGDgYJKoZIhvcNAQcCoILF..."}
If I print the $_POST variable I get an Array(), sometimes empty sometimes containing a dictionary "receipt-data":"...." (I was not yet able to understand why sometimes it is empty and sometimes not).
Before it started to arrive empty, I tried to print the first element, but got nothing interesting.
Briefly, what is the correct way to intercept such a posting and get the value corresponding to receipt-data?
This the (quite long) Post data of which I took off some chunks in order to remain in the maximum message allowance:
Array
(
[{"receipt-data":"MILOdwYJKoZIhvcNAQcCoILOaDCCzmQCAQExCzAJBgUrDgMCGgUAMIK_KAYJKoZIhvcNAQcBoIK_GQSCvhUxgr4RMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgEDAgEBBAMMATgwCwIBCwIBAQQDAgEAMAsCAQ4CAQEEAwIBGzALAgEPAgEBBAMCAQAwCwIBEAIBAQQDAgEAMAsCARkCAQEEAwIBAzAMAgEKAgEBBAQWAjQrMA0CAQ0CAQEEBQIDARHWMA0CARMCAQEEBQwDMS4wMA4CAQkCAQEEBgIEUDIzMTAYAgEEAgECBBB/lJHT84oy2t4czXgoc79YMBsCAQACAQEEEwwR
[...]
Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjANBgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14t_2Mm9zzd5vydtJ3ME\/BH4WDhRuZPUc38qmbQI4s1LGQEti_9HOb7tJkD8t5TzTYoj75eP9ryAfsfTmDi1Mg0zjEsb_aTwpr\/yv8WacFCXwXQFYRHnTTt4sjO0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UXF6jcfiI1yiXV2Q\/Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4REjwYDieFfU9JmcgijNq9w2Cz97roy\/5U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU_12TZ\/wYdV2aeZuTJC_9jVcZ5_oVK3G72TQiQSKscPHbZNnF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAcswggHHAgEBMIGjMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECgwKQXBwbGUgSW5jLjEsMCoGA1UECwwjQXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMxRDBCBgNVBAMMO0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zIENlcnRpZmljYXRpb24gQXV0aG9yaXR5AggYWUMhcnSc\/DAJBgUrDgMCGgUAMA0GCSqGSIb3DQEBAQUABIIBADAfG0M5Lzrl9bhrTKD9nR18Q8HO6zC6XaGtCYtf8a7cE8voswN59EkVCr0yMpcwYxmRjTllJBxJwbPKx3u81B7shTzN5xYfe26nuKqDZBZDo7FqWZSDOhcZ\/E6TEylmWg6kHmWXZJuebDFnLKhQwsgl3H\/atOW4eywXAij_OvPBwPiPc9IBgq4u35oqQL5d2YV38ukBi\/ToqT97\/WG5qvb1JsUDdFoqRuJyA4CCaa8dBlZGDJar29_CjsniFJDz9\/NtUcepZTy3T78POFe2cr_Enrl8E9drcrS4xe5Um9R_CVDNwCgoD1bwYA7M5CjrzNO1dqiXLE59d1i3hgSMS4UxnGLGlXFmlF7DZsjwZil7Eec3XtIaJUlLgnkipOuVUqD1nYw6oBAkCursLDC9AlroN5kWMcEXQXRUgRCItvntJoN897cJX6uXpaaSbiDgXbrwTqnM3/tzHjJgI5T68eI5Dp0LDdxT5FcSd_y3sePf4eTNrJN/eQDMb44ytDg7GOIsG/qiPyHzunp2FrTZZWBIdDP1MvFmLsRoDqvutNqmX5lw3Hobghzk] => "}
)
Upon parsing it with:
$json=json_encode($_POST);
$data=json_decode($json, TRUE);
$data takes the form:
{"{\"receipt-data\":\"MILP9wYJKoZIhvcNAQcCoILP6DCCz_QCAQExCzAJBgUrDgMCGgUAMIK\/qAYJKoZIhvcNAQcBoIK\/mQSCv5Uxgr_RMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgEDAgEBBAMMATgwCwIBCwIBAQQDAgEAMAsCAQ4CAQEEAwIBGzALAgEPAgEBBAMCAQAwCwIBEAIBAQQDAgEAMAsCARkCAQEEAwIBAzAMAgEKAgEBBAQWAjQrMA0CAQ0CAQEEBQIDARHWMA0CARMCAQEEBQwDMS4wMA4CAQkCAQEEBgIEUDIzMTAYAgEEAgECBBB5fbMSc4WXteSuDDZ20X4pMBsCAQACAQEEEwwRUHJvZHVjdGlvblNhbmRib3gwHAIBBQIBAQQU6dWy7_Sty19JvZ97C3lbZ7GoJG4wHgIBDAIBAQQWFhQyMDE1LTAxLTAxVDIwOjU4OjUxWjAeAgESAgEBBB
[...]
b24gQXV0aG9yaXR5AggYWUMhcnSc\/DAJBgUrDgMCGgUAMA0GCSqGSIb3DQEBAQUABIIBABjGnbWvGn1GhGrK99iWdL_fezRcgTN961IxTFvxt0Ob69SEgVgM\/99DbAOdE5xmVNkXucdNXY6RakQ\/CgoD1bwYA7M5CjrzNO1dqiXLE59d1i3hgSMS4UxnGLGlXFmlF7DZsjwZil7Eec3XtIaJUlLgnkipOuVUqD1nYw6oBAkCursLDC9AlroN5kWMcEXQXRUgRCItvntJoN897cJX6uXpaaSbiDgXbrwTqnM3\/tzHjJgI5T68eI5Dp0LDdxT5FcSd_y3sePf4eTNrJN\/eQDMb44ytDg7GOIsG\/qiPyHzunp2FrTZZWBIdDP1MvFmLsRoDqvutNqmX5lw3Hobghzk":"\"}"}
It is the result of executing the objective-c code:
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:storeURL];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSDictionary *requestContents = #{
#"receipt-data": [self.receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:requestData];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:theRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
[...]
From looking at the code that creates the request we can see that it is sending the data formatted as JSON, so you will first want to run it through json_decode, e.g.
$data=json_decode($_POST[0], TRUE);
You don't need to run it through json_encode first as it has already been sent to you as JSON.
Then for the "receipt-data" value itself, we can see that the objective-c code encodes it as base64, so you need to decode it using base64_decode:
$data['receipt-data'] = base64_decode($data['receipt-data']);
I'm trying to retrieve json data from mysql database in iphone. This is my .php file.
I would like to retrieve this data so that I have some code in my .m
- (void)jsonParse{
NSString* path = #"http://phdprototype.tk/getResultData.php";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary* resultDic = [dic objectForKey:#"maxid"];
NSString* recData = [resultDic objectForKey:#"recommendData"];
NSString* rData = [resultDic objectForKey:#"room"];
NSString* lData = [resultDic objectForKey:#"level"];
NSLog(#"recommendData = %#, room = %#, level = %#",recData,rData,lData);}
What I expect is to get data from recommendData, room, and level, but the debugger windows shows it did not get anything. This is what the debugger shows
2014-03-12 15:13:21.500 Semantic Museum[24289:907] recommendData = (null), room = (null), level = (null)
do I miss something??
Looks a problem with the server response headers.
I am seeing the Content-Type come back as
text/html
but it should be something like
application/json
This issue is coming because it's static text(try to View Source in your browser, it's returning extra parameter with JSON). If it's JSON, you need to check that from PHP the header value is set properly.
Why does this not send a http request? i'm trying to add all friends from the person logged in into the mysql table. When i use this url manually in my browser http://www.ratemyplays.com/api/post_friends.php?name=%#&id=%#&userid=%#
it add the values %#, but not when i run the objective-c code. What am i doing wrong with the http request loop?
for (NSDictionary<FBGraphUser>* friend in friends) {
NSString *strURL = [NSString stringWithFormat:#"http://www.ratemyplays.com/api/post_friends.php?name=%#&id=%#&userid=%#",friend.name, friend.id, currentId];
// to execute php code
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
// to receive the returend value
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%#", strResult);
}
I think you need to be more clear what are you trying to accomplish here.. the Url that nslog prints out looks fine.. what do you mean by adding %#? all you did in this look is creating again and again -one- string of URL and didn't do anything with it...
Well, I decided that it's time to learn a new skill, programming objective-c. My programming knowledge is very minimal, It consists of PHP, little bit of HTML, and a little bit of MySQL. What I want to do is take some JSON that is made with php and populate a iOS table view.
here is my json.php:
<?php
$array = array(1,2,3,4,5,6,7,8,9,10);
$json = json_encode($array);
echo $json;
?>
My only problem is, is I have no idea where to start on how to use JSONKit framework. https://github.com/johnezang/JSONKit/ I would prefer to use JSONKit over the other alternatives just because it seems it has more support.
NSString *strURL = [NSString stringWithFormat:#"http://api.tekop.net/json.php"];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%#", strResult);
I was able to print the results of the JSON page in the debug console. Now my only question is what next? I have tried to look for some tutorials online but all I could find was something more advanced Jason phraser. To advanced for my basic needs. I know my questions very vague and open to a lot of different answer, but I figured this is the place to ask these types of questions.
iOS has its own JSON parse now called NSJSONSerialization.
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html
You can have a look. I always use it like this.
[NSJSONSerialization JSONObjectWithData:tmpData
options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments
error:nil]
sample by modifying your code:
NSString *strURL = [NSString stringWithFormat:#"http://api.tekop.net/json.php"];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSArray *arrayResult = [NSJSONSerialization JSONObjectWithData:dataURL
options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments
error:nil];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
Something to note is that, if your json is an array based, use NSArray to store the result. If your json is an hash based, use NSDictionary. (Hope I say it clearly, I dont know the related terms to describe)
What have you tried?
NSArray *array = [dataURL objectFromJSONData];
NSAssert([array isKindOfClass:[NSArray class]], #"This should be an array.");
for (NSNumber *value in array) {
NSAssert([value isKindOfClass:[NSNumber class]], #"This should be a number.");
NSLog(#"%#", value);
}