I like your blog and usually find a lot of answers to my questions, but this time I am struggling. I have a PHP web server that generates JSON output on request.
On the other side I have an iPhone application trying to extract information from that server, using requests.
The issue is that anytime accented characters are printed out from the PHP server, the answer comes as field on the iPhone.
Here is my PHP code:
// Return a dictionary (array of element/values)
// Partial code of the PUser class
function dictionary()
{
$array = array();
foreach( $this->Fields as $field )
{
$value = $field->GetValor(true);
$array[$field->Nome] = utf8_encode( $value ); // I tried here several encoding methods
}
return $array;
}
// Header
header('Content-Type: text/html; charset=utf-8', true);
$sql = "SELECT * FROM users";
$query = db_query($sql);
$nbrows = db_num_rows($query);
$array = array();
$array["Users"] = array();
$user = new PUser;
for( $i=0; $i<$nbrows; $i++ )
{
$user->Read($query);
$array["Users"][] = $user->dictionary();
}
$json = json_encode( $array );
echo $json;
On the other hand, I have the iPhone code (extracted from the site http://stig.github.com/json-framework/):
// User action
-(IBAction)onRedo:(id)sender
{
adapter = [[SBJsonStreamParserAdapter alloc] init];
adapter.delegate = self;
parser = [[SBJsonStreamParser alloc] init];
parser.delegate = adapter;
parser.supportMultipleDocuments = YES;
NSString *url = @"http://wy-web-site"; // The web site I am pushing the date from
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
}
#pragma mark 开发者_如何转开发-
#pragma mark SBJsonStreamParserAdapterDelegate methods
- (void)parser:(SBJsonStreamParser *)parser foundArray:(NSArray *)array
{
[NSException raise:@"unexpected" format:@"Should not get here"];
}
- (void)parser:(SBJsonStreamParser *)parser foundObject:(NSDictionary *)dict
{
NSLog(@"parser foundObject: %@", dict );
}
#pragma mark -
#pragma mark NSURLConnectionDelegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"Connection didReceiveResponse: %@ - %@, encoding: %@", response, [response MIMEType], [response textEncodingName]);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"Connection didReceiveData of length: %u", data.length);
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"Data: %@", str );
[str release];
// Parse the new chunk of data. The parser will append it to
// its internal buffer, then parse from where it left off in
// the last chunk.
SBJsonStreamParserStatus status = [parser parse:data];
if (status == SBJsonStreamParserError)
{
NSLog(@"%@", [NSString stringWithFormat: @"The parser encountered an error: %@", parser.error] );
NSLog(@"Parser error: %@", parser.error);
} else if (status == SBJsonStreamParserWaitingForData)
{
NSLog(@"Parser waiting for more data");
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Finish loading");
}
Then what I get is: From the PHP server:
{"Users":[{"fs_firstname":"Jo\u00e3o","fs_midname":"da","fs_lastname":"Silva"]}
From the iPhone (NSLog)
2011-07-08 12:00:24.620 GAPiPhone[94998:207] Connection didReceiveResponse: <NSHTTPURLResponse: 0x6f458c0> - text/html, encoding: (null)
2011-07-08 12:00:24.620 GAPiPhone[94998:207] Connection didReceiveData of length: nnn
2011-07-08 12:00:24.620 GAPiPhone[94998:207] Data: {"Users":[{"fs_firstname":null,"fs_midname":"da","fs_lastname":"Silva","}]}
2011-07-08 12:00:24.621 GAPiPhone[94998:207] parser foundObject: {
Users = (
{
"fs_firstname" = "<null>";
"fs_midname" = da;
"fs_lastname" = Silva;
}
);
}
As we can see my encoding is null in the answer, even if http header has been specified in the PHP server side.
Thank you for all your inputs.
Your Content-Type header indicates that the data is UTF-8, but you seem to be trying to parse it as ASCII. What happens if you change this:
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
to this:
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
?
精彩评论