So I'm fetching a JSON string from a php script in my iPhone app using:
NSURL *baseURL = [NSURL URLWithString:#"test.php"];
NSError *encodeError = [[NSError alloc] init];
NSString *jsonString = [NSString stringWithContentsOfURL:baseURL encoding:NSUTF8StringEncoding error:&encodeError];
NSLog(#"Error: %#", [encodeError localizedDescription]);
NSLog(#"STRING: %#", jsonString);
The JSON string validates when I test the output. Now I'm having an encoding issue. When I fetch a single echo'd line such as:
{ "testKey":"é" }
The JSON parser works fine and I am able to create a valid JSON object. However, when I fetch my 2MB JSON string, I get presented with:
Error: Operation could not be completed. (Cocoa error 261.)
and a Null string. My PHP file is UTF8 itself and I am not using utf8_encode() because that seems to double encode the data since I'm already pulling the data as NSUTF8StringEncoding. Either way, in my single-echo test, it's the approach that allowed me to successfully log \ASDAS style UTF8 escapes when building the JSON object.
What could be causing the error in the case of the larger string?
Also, I'm not sure if it makes a difference, but I'm using the php function addslashes() on my parsed php data to account for quotes and such when building the JSON string.
I'm surprised no one has mentioned using a different encoding value instead of NSUTF8StringEncoding when calling [NSString stringWithContentsOfFile:encoding:error:].
I also got Cocoa error 261 when parsing a JSON file. I just went through the list of NSString encodings until one worked. Fortunately the first one worked for me: NSASCIIStringEncoding!
You can also use NSString stringWithContentsOfFile:usedEncoding:error: to try to find the correct encoding (as described here: How to use stringWithContentsOfURL:encoding:error:?).
Don't know if this is your problem, but I just had a similar thing (stringWithContentsOfFile, no JSON), and the problem was that the file had CRLF (windows) line-endings and Western-whatever-it's-called encoding. I used SubEthaEdit to convert to LF (Mac/Unix line-endings) and UTF-8 encoding, and now everything works fine.
Encoding issue: Cocoa Error 261? I solved this issue by trying different encoding. First I was using NSUTF8 then I switched to NSASCIIStringEncoding and it worked.
NSString* path = [[NSBundle mainBundle] pathForResource: #"fileName" ofType: #"type"];
NSData* data = [NSData dataWithContentsOfFile:path];
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"%#",string);
For future reference, if you need to override the encoding, and you're working with streams without embedded NULs, something like this might be good (I've just written a rough sketch outline here, check this code is and does want you want before using it):
NSHTTPURLResponse* resp=nil;
NSData* jsonAsImmutableData = [NSURLConnection sendSynchronousRequest:
[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://<whatever>"]]
returningResponse:&resp error:NULL];
NSMutableData*modifiedData = [NSMutableData dataWithData:jsonAsImmutableData];
char extraNulls[7] =
{0,0,0,0,0,0,0}; // is this defensive enough for your encoding?
[modifiedData appendBytes:extraNulls length:7];
NSString* jsonAsString = [NSString stringWithCString:[modifiedData bytes]
encoding:<whatever your encoding is>];
But I expect your best course of action is to check that your server is both using and claiming to use UTF-8 encoding or some other Apple iPhone supported encoding.
EDIT
altered code comment.
What helped me was just to change the physical file encoding to UTF-8. My editor had set it to the default, MacRoman, and didn't like letters with accents.
Related
I have a strange text encoding problem that I can't figure out. The strange this is that if you check out the text online from the API feed in a browser the text doesn't need any formatting.
Here's my code:
-(void) viewDidLoad {
[super viewDidLoad];
NSString *jsonDealString = [NSString stringWithFormat:#"http://api.*****"];
NSLog(#"deal id is %#",dealId);
// Download the JSON
NSString *jsonString = [NSString
stringWithContentsOfURL:[NSURL URLWithString:jsonDealString]
encoding:NSStringEncodingConversionAllowLossy|NSUTF8StringEncoding
error:nil];
// Create parser for the api
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
[self setDisplayItems:[results objectForKey:#"results"]];
NSDictionary *item = (NSDictionary *)[displayItems objectAtIndex:0];
self.titleDeal.text = [item objectForKey:#"title"];
}
I was able to correct the text encoding problem using:
// merchant name with encoding fix
NSString *correctStringTitleDeal = [NSString stringWithCString:[[[item objectForKey:#"merchant"] objectForKey:#"name"] cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding];
self.titleDeal.text = correctStringTitleDeal;
But that caused a crash when a Null object was encountered.
my crash log output states:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* +[NSString stringWithCString:encoding:]: NULL cString'
Here's a screenshot of the problem occurring in a table view (it's occurring elsewhere in the app too):
thanks for any help
The crash is because you are sending a message to a c-string, not to an object. cstringUsingEncoding: gives a c-string and you cannot do things like encode:
For the encoding problem, if you can read well the text from the API using a browser, then it is encoded for HTML instead of unicodes in UTF8 form.
Short answer: Find out the string encoding of the API and use it.
Longer answer:
The most likely cause of encoding problems is that the JSON isn't in UTF-8. JSON is required by spec to be in some form of Unicode (see RFC4627 Section 3). The speicifc encoding is determined by the first four octets. Again, see the spec.
Your passing of NSStringEncodingConversionAllowLossy is extremely suspicious. You should not be allowing lossy conversion. You should know the specific encoding of the API and you should use it. Similarly, you switch encoding in your other example code to NSISOLatin1StringEncoding. While this is similar to some Unicode, it is not a Unicode encoding as so never should be used for JSON.
It's of course possible that this particular API is in violation of spec and is sending badly encoded JSON. You can either work with the API provider to fix their JSON, or you can use whatever encoding they are providing. But you shouldn't guess, and you definitely shouldn't accept lossy conversions.
I am facing a peculiar problem in parsing some xml data within my iPhone application. When I pass the xml data to NSXMLParser class for parsing, it ignores the part where the actual data starts appearing. It shows all the element names just before the data appears such as Soapenvolopebody etc. Later, I observed that the tags are appearing with '<'; and '>';symbols which is causing the problem.
I hope this requires a replacement strategy before parsing it to NSXMLParser. My questions is why iPhone is taking XML in that way? I am generating xml dynamically from a php file and comes as an XML when loaded into IE Browser. Hope you can help me to resolve the issue.
Update
I am still looking for a solution. I think the the idea of converting NSString to NSData and then passing it to NSXMLParser could accomplish parsing.
NSString* str= #"teststring";
NSData* data=[str dataUsingEncoding:NSUTF8StringEncoding];
I found this mentioned in the following post which I will be trying out. How do I convert an NSString value to NSData?
Update 1
I get the data in NSData format. Converted to NSString and applied replacement code to done away with < and > stuff. After that, I again converted the replaced NSString to NSData format. But still the xml is not correctly parsing using NSXMLParser.
please replace the unwonted character using this string function. please refer the below code.
NSString *theXML = [[[NSString alloc] initWithBytes: [webdata mutableBytes] length:[webdata length] encoding:NSUTF8StringEncoding]autorelease];
theXML = [theXML stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
theXML = [theXML stringByReplacingOccurrencesOfString:#">" withString:#">"];
theXML = [theXML stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSLog(#"%#",theXML);
Thanks
I have an external XML file which I want to be represented in an NSData object
I am doing this;
NSError *error;
NSString* contents = [NSString stringWithContentsOfUrl:[NSURL URLWithString:#"http://www.apple.com/"]
encoding:NSUTF8StringEncoding
error:&error];
NSData* xmlData = [contents dataUsingEncoding:NSUTF8StringEncoding];
But for some reasons, I am getting an error (does not respond)
Please help me.
Don't have time to test this out but I think you may want to try looking into NSData's dataWithContentsOfURL: or dataWithContentsOfURL:options:error: and get it directly as data.
Also, unless you just threw http://www.apple.com/ in as a placeholder, I don't believe the source of that page is valid XML. The following feed is valid xml: https://stackoverflow.com/feeds You could try that. with what you have now first and see if it works.
Hope this helps.
Updated:
Without my knowing your project, you may get some benefit from using TouchXML - https://github.com/mrevilme/TouchXML which handles XML very well including what you are trying to do:
CXMLDocument *xmlDoc = [[CXMLDocument alloc] initWithContentsOfURL:(NSURL *)inURL encoding:(NSStringEncoding)encoding options:(NSUInteger)inOptions error:(NSError **)outError];
In my program, I'm allowing the user to input some words into a textfield. Then my program will use these words to form a html string. The string will then be used in NSURL so I can connect to the website.
This method works great for english words. But when I input some chinese (or korean) in there, I does not work. Thus I believe that I need to convert the inputed data before passing it to NSURL. However I could not find a way to do this.
Here's an example of how my code looks like.
NSString *searchedString = theSearchBar.text;
NSString *urlToBeSearched = [[NSString alloc]
initWithFormat:#"http://www.awebsite.com/search/%#",
searchedString];
NSURLRequest *urlRequest = [[NSURLRequest alloc]
initWithURL:[NSURL URLWithString:urlToBeSearched]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:50];
NSURLConnection *tempCon =[[NSURLConnection alloc] initWithRequest:urlRequest
delegate:self];
Then of course releasing them later.
For example, when searchedString = 你好, the urlLink will be http://www.awebsite.com/search/你好. NSURLConnection doesn't like that and will give me "Bad Url" error.
However, if the urlLink is "%E4%BD%A0%E5%A5%BD" it will give me the correct link.
The set of characters allowed in a URI is pretty much limited to a subset of US-ASCII (see RFC2396). That means your Chinese characters must be percent escaped in the URI. The documentation for NSURL +URLWithString: says the string must conform to the RFC so you need to percent escape the string before calling that method.
Fortunately, NSString has a method that will allow you to do that called -stringByAddingPercentEscapesUsingEncoding:. You still need to choose a suitable encoding and which one you choose depends on how the server decodes the URL string. The easiest option is probably to use UTF-8 at both ends. You need to do something like:
NSString* searchedString = [theSearchBar.text stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSString* urlToBeSearched = [NSString stringWithFormat:#"http://www.awebsite.com/search/%#", searchedString];
// everything else the same, except you don't need to release urlToBeSearched
Did you try encoding your search-string?
[NSString stringByAddingPercentEscapesUsingEncoding:/encoding-of-choice/];
Not sure what encoding you would use for chinese characters though.
I am aware this question has been asked several times, but I was unable to find a definate answer that would best fit my situation.
I want the ability to have the user select an image from the library, and then that image is converted to an NSData type. I then have a requirement to call a .NET C# webservice via a HTTP get so ideally I need the resulting string to be UTF8 encoded.
This is what I have so far:
NSData *dataObj = UIImageJPEGRepresentation(selectedImage, 1.0);
[picker dismissModalViewControllerAnimated:YES];
NSString *content = [[NSString alloc] initWithData:dataObj encoding:NSUTF8StringEncoding];
NSLog(#"%#", content);
The NSLog statement simply produces output as:
2009-11-29 14:13:33.937 TestUpload2[5735:207] (null)
Obviously this isnt what I hoped to achieve, so any help would be great.
Kind Regards
You can't create a UTF-8 encoded string out of just any arbitrary binary data - the data needs to actually be UTF-8 encoded, and the data for your JPEG image obviously is not. Your binary data doesn't represent a string, so you can't directly create a string from it - -[NSString initWithData:encoding:] fails appropriately in your case.
Assuming you're using NSURLConnection (although a similar statement should be true for other methods), you'll construct your NSMutableURLRequest and use -setHTTPBody: which you need to pass an NSData object to. I don't understand why you would be using a GET method here since it sounds like you're going to be uploading this image data to your web service - you should be using POST.