iOS utf-8 encoding issue - ios

i try get html page with UTF-8 charset
NSString *html=[NSString stringWithContentsOfURL:[NSURL URLWithString: #"http://forums.drom.ru/general/t1151288178.html"] encoding:NSUTF8StringEncoding error:&error]);
but NSLog(#"%#",html) return null
Why is this happening?

The problem is that while the file's meta tag purports to be UTF8, it's not (at least not entirely). You can confirm this by:
Download the html (as NSData, which succeeds):
NSError *error = nil;
NSURL *url = [NSURL URLWithString:#"http://forums.drom.ru/general/t1151288178.html"];
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filename = [docsPath stringByAppendingPathComponent:#"test.html"];
[data writeToFile:filename atomically:YES];
Run iconv from the Terminal command line, it will report an error (including line number and character number):
iconv -f UTF-8 test.html > /dev/null
Thanks to Torsten Marek for sharing that with us.
When I look at that portion of the HTML, there are definitely not UTF8 characters there, buried in the setting of the clever_cut_pattern JavaScript variable.
If we thought you just got the encoding wrong, the typical counsel in these cases would generally be to use the rendition of stringWithContentOfURL with the usedEncoding parameter (i.e. rather than guessing what the encoding is, let NSString determine this for you):
NSStringEncoding encoding;
NSString *html = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:&error];
Unfortunately, in this case, even that fails (presumably because the file purports to be UTF8, but isn't).
The question then becomes "ok, so what do I do now". It depends upon why you were trying to download that HTML in your app, anyway. If you really need to convert this to UTF8 (i.e. strip out the non-UTF8 characters), you could theoretically get the GNU iconv(3) function, which is part of the libiconv library. That could identify non-conforming characters that you could presumably remove. It's a question of how much work you're willing to go through to handle this non-conforming web page.

Related

How should an iOS library handle logging to a file on iPhone's file system?

I am working on an iOS library project and need to create an API that takes an NSString parameter which is a path, and the library will write some debugging messages to a file in that path.
I've done some research about logging onto a file in iPhone's file system, one approach is using
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
This will redirect any following NSLog to a file...
While this seems easy, I have a question: Will this also redirect the API consumer's application(calling application)'s NSLog to the file? I don't want this behavior because I want to be able to control what goes in there as a library..
If that is the behavior, what other approach I can use to achieve my requirement? Thanks.
If I understood correctly, the desired functionality is to pass a path and write some debugging info to a file on that path? If that is so, I don't think you should redirect all your NSLog calls to a file; just using the NSString writeToFile: would be enough:
-(void)writeToFile:(NSString*)path {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:path];
NSError *error=nil;
NSString *myMessage="This is the data to write to the file";
[myMessage writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:&error];
}
If you want to append to that file, you can use the NSFileHandle functionality - check the docs here.

RNCryptor: Encrypt with rncrypt (cli) then decrypt in iOS using RNDecryptor

When I use the terminal version of RNCryptor to encrypt a file and then try to decrypt this file in Objective-C using RNDecryptor, I always get the error "unknown header".
I understand this is because my first byte is 'A' instead of '2' or the kRNCryptorFileVersion, but I don't know why this is.
If I decrypt the file using the terminal version, it works like expected.
I encrypt the file using:
./rncrypt -p someKey "$(cat test.txt)" > encr.txt
This gives output like:
AwHcVbXbpyI7S/RBXlVhRP1coKqFmSEFDtgFaj/JGJ181qEb024uVdt7lHWqUvUvm1rwdM4yQQ+gsMepHhR58v054qvhO4yu98N2bHGuV28aUA==
To decrypt it in iOS I'm doing the following:
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"encr" ofType:#"txt"];
NSData *data = [NSData dataWithContentsOfFile:resourcePath];
NSError *error;
NSData *uncrypted = [RNDecryptor decryptData:data withPassword:#"someKey" error:&error];
What am I doing wrong?
The rncrypt test program outputs base64 encoded data. You need to decode it before passing it to the decryptor. See [NSData initWithBase64EncodedData:options:].
Note that if kRNCryptorFileVersion is 2, you're using a slightly broken version of RNCryptor that has poor security for multibyte passwords (Chinese for example). I highly recommend using a later version with the v3 format.

Make a local NSURL from an NSString containing HTML?

I have an NSString containing some HTML. I’m trying to pre-load that HTML, including any external image links inside it. So, to clarify: I have just HTML, and I need to basically load it, grab its images, and cache that data.
I can do this with a live website using the following code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:#"%#/%#", [paths objectAtIndex:0], #"index.html"];
NSURL *url = [NSURL URLWithString:#"http://www.google.co.uk"];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
But this won’t work without an NSURL. I’m wondering if I can make an NSURL somehow from this string of HTML, and substitute it in the URLWithString: method here.
So, question: can I take some local HTML inside an NSString and turn that into an NSURL, so that I can feed it into the code above, and save the both the HTML and any images it links to?
The question you are asking makes absolutely no sense.
A URL is a pointer to the location of a resource online. In this context a html file. You can not make one into the other.
I suggest you create a UIWebView, load the string into that, have it render and cache the result.
[webView loadHTMLString:#"data" baseURL:nil];
I believe it will need to be actually place on the screen for it to render, so make it an invisible 1 X 1 pixel square and it should be fine. Then when the didFinishLoading fires. Cache the result
Yes, you can. You would have to parse the links out of HTML yourself. Real world HTML is not XML compliant, so a quick and dirty way to achieve your goals would be to treat HTML as text and parse links out using a regular expression library.

cant get 100,000+ hebrew characters into objective-c string

I have 100,000+ characters of text that need to be converted into a string so I can count the characters and display them on a page correctly, but in the text there are tons of quotations ("") and lots of commas, so it doesnt even turn into a string.
Does anyone know a way that you can ignore quotations and commas inside a NSString without having to do this \"" each time?
Here's some of the text. its english/hebrew
Psalm 30
...
Psalm 100
...
The following Psalm is not to be said on Shabbat, Festivals, the day before Pesach, Chol HaMoed Pesach, and the day of Yom Kippur
...
You say “I cant even turn the text into a string”. Since you said (in a comment) you're “just pulling it off this website”, the simplest way to do this is +[NSString stringWithContentsOfURL:encoding:error:]. This works for me:
NSURL *url = [NSURL URLWithString:#"http://opensiddur.org/wp-content/uploads/2010/08/The-Blessing-Book-Nusa%E1%B8%A5-Ha-Ari-%E1%B8%A4aBaD-3.2.txt"];
NSError *error;
NSString *text = [NSString stringWithContentsOfURL:url usedEncoding:nil error:&error];
NSLog(#"error=%# text.length=%lu", error, (unsigned long)text.length);
You can look into NSURLSession or NSURLConnection when you want to do it in a non-blocking fashion.
If you plan to distribute the text in a file (named, let's say, “blessingBook.txt”) in your app bundle, you can get the URL this way:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"blessingBook" withExtension:#"txt"];
If you're loading it directly from your app bundle, you probably don't need to worry about using NSURLSession to load it in the background. You might want to do your “processing” in the background though, if it takes a while.
You can replace the punctuation or commas or what ever you want to #"" (empty string).
yourString=[yourString stringByReplacingOccurrencesOfString:#"," withString:#""];
yourString=[yourString stringByReplacingOccurrencesOfString:#":" withString:#""];
yourString=[yourString stringByReplacingOccurrencesOfString:#";" withString:#""];
What ever the text you want to replace. Replace as above.
But it is lengthy process finding un wanted quotations, commas..some characters and replace with empty string..
Hope it helps you..!

How to read content from plain text remote file with objective-c

I want to read a list (in plain text) from a remote file line by line.
I have found some answers but they're not the ones I'm looking for.
p.s. I've been programing in objective-c and developing in iOS for about 2 months, I'm a rookie i might not understand or recognize some terms. Please answer like you are talking to a beginner.
If i am not wrong you just want to read a text from remote file, so here it is.
NSString * result = NULL;
NSError *err = nil;
NSURL * urlToRequest = [NSURL URLWithString:#"YOUR_REMOTE_FILE_URL"];//like "http://www.example.org/abc.txt"
if(urlToRequest)
{
result = [NSString stringWithContentsOfURL: urlToRequest
encoding:NSUTF8StringEncoding error:&err];
}
if(!err){
NSLog(#"Result::%#",result);
}
To load the remote txt file, you should take a look at NSURLConnection or AFNetworking (there are other possibilities, these two are probably the most common).
You will then get the content of the file. Depending on what you intend to do with it, you may have to parse it, either with something as simple as -[NSString componentsSeparatedByString:] or with something a bit more powerful like NSScanner.
There are three steps involved in loading a file
create the object that specifies the location of the file
call the appropriate NSString class method to load the file into a
string
handle the error if the file is not found
In step 1, you need to either create an NSString with the full path to the file in the file system, or you need to create an NSURL with the network location of the file. In the example below, the code creates an NSURL since your file is on the network.
In step 2, use the stringWithContentsOfFile method to load a file from the file system, or the stringWithContentsOfURL method to load a file from the network. In either case, you can specify the file encoding, or ask iOS to auto-detect the file encoding. The code below auto detects while loading from the network.
In step 3, the code below dumps the file to the debug console if successful or dumps the error object to the console on failure.
Missing from this code is multithreading. The code will block until the file is loaded. Running the code on a background thread, and properly notifying the main thread when the download is complete, is left as an exercise for the reader.
NSURL *url = [NSURL URLWithString:#"www.example.com/somefile.txt"];
NSStringEncoding encoding;
NSError *error;
NSString *str = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:&error];
if ( str )
NSLog( #"%#", str );
else
NSLog( #"%#", error );

Resources