I'm trying to show content of text file with unknown encoding according to Apple's documentation:
Try stringWithContentsOfFile:usedEncoding:error: or initWithContentsOfFile:usedEncoding:error: (or the URL-based equivalents). These methods try to determine the encoding of the resource, and if successful return by reference the encoding used.
If (1) fails, try to read the resource by specifying UTF-8 as the encoding.
If (2) fails, try an appropriate legacy encoding. "Appropriate" here depends a bit on circumstances; it might be the default C string encoding, it might be ISO or Windows Latin 1, or something else, depending on where your data is coming from.
This is not always working. Is there more reliable ways to detect encoding?
You should use NSAttributedString which can detect encoding. After long time testing different solutions, I use that:
NSError *error;
NSDictionary *options = [NSDictionary dictionary];
NSDictionary *attributes;
NSAttributedString *theString = [[NSAttributedString alloc] initWithURL:fileURL options:options documentAttributes:&attributes error:&error];
NSInteger detectedEncoding = [[attributes objectForKey:#"CharacterEncoding"] integerValue];
I tested many files from many sources/environment, and it seem to be efficient (thus you should check whether error is nil or not). For a plain csv file exported from Excel, I get this attributes dictionary (30 value means NSMacOSRomanStringEncoding:
{
CharacterEncoding = 30;
DocumentType = NSPlainText;
UTI = "public.plain-text";
}
If you do not know the encoding of the data ahead of time, then it has to be guessed through analysis of the raw data, and that can sometimes lead to wrong guesses and thus unreliable decoding. When in doubt, just ask the user which encoding to use.
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.
Is there a way to parse an XML in iOS where the attribute are not separated
e.g:
Users
UserId="1" Name="John Smith" Loc="London"
UserId="2" Name="Johnny Cash" Loc="Nashville"
Users
Thanks
It seams like you havent got xml at all. You are missing all usefully symbols that would normally help with the parsing. You taks is to parse a new format specification.
My first bit of advice is to ask whoever is providing you with this feed to put it into a proper format (JSON or plist are the easiest to work with).
Failing this, if the feed is not too big (otherwise you will hit performance issues), parse the feed manually character by character. You probably want to write a event based parser.
Split the feed line by line, perhaps using componentsSeparatedByString:
Then read characters into a string untill you hit an = that string is your key. Next read between the quotes "" That string is your value. FIre the key and the value off to a delegate.
JSON parsing classes will help you out...
NSString *responseString = #""; // your data contained string.
SBJSON *json = [[SBJSON new] autorelease];
NSArray *resultData = [json objectWithString:responseString error:&error];
I'm allowing the users of my app to either take a pic or select one from their library. When selected I need to get the images' data and convert it to a string so I can send it to a web service.
The problem I'm currently having is that [NSString initWithData:] is returning nil when I have the encoding set to UTF8. I need to set it to UTF8 for the XML message.
NSString *dataString = [[NSString alloc] initWithData:UIImageJPEGRepresentation(theImage, 1.0) encoding:NSUTF8StringEncoding];
Thanks for any advice!
You can't convert an UIImage to NSString by using initWithData:encoding: method. This method is only for converting an string's data to NSString (an Text File for example).
If you are trying to convert any kind of binary data to NSString, there are some kind of encoding available. Base64 is widely used. Also your server should have the ability to decode what you've sent.
In addition, in most cases, send an image to server just need to POST it in binary as it used to be.
I'm a young iPhone developer and I'm trying to write an iPhone app that syncs data from a server side app on my mac, basically text data.
I'm having trouble reading data on the iPhone side with the following:
`
(void)connectionReceived:(NSNotification *)aNotification {
NSFileHandle *incomingConnection = [[aNotification userInfo] objectForKey:NSFileHandleNotificationFileHandleItem];
[[aNotification object] acceptConnectionInBackgroundAndNotify];
NSData *receivedData = [incomingConnection availableData];
NSString *theString = [[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease];
`
I need to print out theString to a text label on the iPhone, but what I get is the exact "hex code translation" of the text entered on the server side app and I don't seem to be able to convert it to char.
Can anyone help ?
I don't know the answer - but there are a few things to look at or try:
Did you try converting into something other than UTF8? (Unicode? ASCII?)
In the hex output it gives you - I assume it is giving a UTF8 representation - i.e. one 8-bit (two hex nibble) code for each character in your string. Is this the case? Are the hex codes "correct" for a UTF-8 or ASCII representation of your string?
Are there any "bad" codes in the result?
I am wondering if this is happening because there are characters (maybe even invisable ones - control characters - nulls, whatever) in your string which are making it so iOS can't do a "normal" UTF8 conversion...
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.