I have a language file downloaded from a web service located in my resources folder of the project. The file name is "no.properties" and I need to load the file into a string to make further use of it..
The content of my file is displayed like this:
CMD_EXIT = Avslutt
CMD_PAUSE = Pause
CMD_SCAN = Skann
ect.....
Here is my code of loading the file into a string:
NSString* path = [[NSBundle mainBundle] pathForResource:[defaults objectForKey:#"language"]
ofType:#"properties"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
The problem is that the "content" string is null even though the file contains a lot of data. Anyone know what might be the problem?
note: I´ve checked that the value received from userdefaults equals "no". I have also tried to rename the file to "no.txt", but still the "content" string is null.
First, you could try to pass a NSError object to stringWithContentsOfFile:::.
You should receive a Cocoa error number, that (hopefully) tells you more about the problem.
NSError* err = nil;
NSString* string = [NSString stringWithContentsOfFile:path encoding:NSUTF16BigEndianStringEncoding error:&err];
As you seem to work with language files, I suspect that you are specifying the wrong encoding when reading in the strings.
Related
I have a weird one for you guys today, I think my NSStrings are incorrectly encoded.
NSString * convertedString = [NSString stringWithUTF8String:mesh->groupMesh[i].materialData->textureName];
-textureName is just a c style string that I'm converting into an NSString.
-The string is: "dennum1.png"
NSArray * line = [convertedString componentsSeparatedByString:#"."];
NSString * texPath = [[NSBundle mainBundle] pathForResource:line[0] ofType:line[1]];
I then split it into an NSArray line, separated by periods "."
This makes it so that line[0] is dennum1, and line[1] is png.
I even do an NSLog to make sure:
NSLog(#"Name:%# Type:%#", line[0], line[1]);
2013-09-21 02:15:27.386 SteveZissou[8846:c07] Name:dennum1 Type:png
I parse this over to the pathForResource function and I get a (null) response.
BUT if I hard type the file name into the code I.E:
convertedString = #"dennum1.png";
NSArray * line = [convertedString componentsSeparatedByString:#"."];
NSString * texPath = [[NSBundle mainBundle] pathForResource:line[0] ofType:line[1]];
NSLog(#"This is the texPath: %#",texPath);
IT WORKS?!
This is the texPath: /Users/meow/Library/Application Support/iPhone Simulator/6.0/Applications/2DEB8076-5F9D-45DE-8A73-10B1C8A084B4/SteveZissou.app/dennum1.png
Is it possible that the NSString that I hard type in the code and the NSString that comes from the conversion are encoded differently?
When I NSLog them individually I get the same result regardless of type:
2013-09-21 02:15:27.386 SteveZissou[8846:c07] This is the c style string: dennum1.png
2013-09-21 02:15:27.386 SteveZissou[8846:c07] This is the converted c style string: dennum1.png
2013-09-21 02:15:27.386 SteveZissou[8846:c07] This is the string manually typed in: dennum1.png
What happens if you use the methods in NSPathUtilities that are designed to handle this stuff. Like:
NSString * texPath = [[NSBundle mainBundle] pathForResource:string.stringByDeletingPathExtension ofType:string.pathExtension];
Also, there's -fileSystemRepresentation which will convert an NSString to a const char * and throw an exception if the string can't be converted correctly.
I figured it out after HOURS of skimming through possible code combinations and found it by accident.
I used NSURL functions to get the path based on the strings I was using, which resulted in this path:
file://localhost/Users/meow/Library/Application%20Support/iPhone%20Simulator/6.0/Applications/2DEB8076-5F9D-45DE-8A73-10B1C8A084B4/SteveZissou.app/dennum2.png%0D
Look at the very end! That's not supposed to be there! Turns out it's called a carriage return and it was pulled with the file (probably a remnant of the files formatting), but invisible to NSLog, however it wasn't invisible to NSURL (NSURL must read the bytes and display what they are?). So snipping the carriage return off the end of the path gave me the correct file and everything is OK.
I kept thinking to myself to use a hex editor to look at the file, but couldn't find one on the mac appstore free, I think if this was windows I would've caught it in half the time.
I have a big text file that I want to convert into Xcode. I added the text file in the main bundle (drag and drop) into my project . I can see the text file viewDidLoad.
But I like to convert it to XML file. For instance my file looks like :
asasasasasas
wewewewewewe
qwqwqwqwqwqw
xyz_ 22 aaaaaaaaaaa
fgfgfgfgfgfgfg
ererererererer
abc_ 12 bbbbbbbbbb
jkjkjkjkjkjkjk
lalallalalalal
In the above mentioned, I want to eliminate the first 3 lines, to start from xyz_ 22 as (parent), jkjkjkj as child lalalala as a child.
I need only the idea how to implement this ... I'll write the code :)
mycode:
- (IBAction)readUsingObjectiveC:(id)pId {
NSString * zStr = [NSString stringWithContentsOfFile:#"/Users/dd007/Desktop/abc.txt" encoding:NSASCIIStringEncoding error:NULL];
NSLog(#"readUsingObjectiveC zStr=\n%#",zStr);
// now to extract the data line by line
NSArray * zAryOfLines = [zStr componentsSeparatedByString:#"\n"];
if([zAryOfLines count] == 0)
{
NSLog(#"readUsingObjectiveC zAryOfLines count = 0");
return;
}
//for (int i=0; i<([zAryOfLines count]-30); ++i)
for ( int i=30; i<zAryOfLines ; i++)
{
if([[zAryOfLines objectAtIndex:i] isEqualToString:#"xyz_ "])
{
NSLog(#"<msg1>%#<msg1/>\n",[zAryOfLines objectAtIndex:i]);
NSLog(#"<msg2>%#<msg2/>\n",[zAryOfLines objectAtIndex:i+1]);
NSLog(#"<msg3>%#<msg3/>\n",[zAryOfLines objectAtIndex:i+2]);
[zArrayOfLines writeToFIle:#"/.....documents/..save.xml" automatically:YES encodingNSASCIIStringEncoding error:NULL];
}
}
I am getting convert into xml format but i like to save the file in .xml .. but i am getting error could any one tell me where i am doing mistake ??????
You can't convert a file to xml using XCode, you have two options:
You can create a python or ruby script that parses your file and makes a XML file, and then use a xml parser,
Or you can create a class that parses your plain file with the rules you want.
I think you want to transform a .txt to a .xml so for make this i read the .txt to a nsstring i cut this into a NSArray with componentsSeparatedByString:#"\n" method of NSString (take care of \r character) and after just don't take line you don't want and create a new NSString for add tag XML to your line if you now where place the good tag or check it with the contains of your line in the NSArray for finish just saved in new file with extension .xml.
If you need help for write code like i describe say it.
There is no option for converting the text to xml directly in iOS.
But you can do it by passing the data manually.
You can use either libXml framework or GDataXml for doing this.
For libXml xml generation sample code go to this link and download Chapter 10.zip
Please check this tutorial for Read and Write XML Documents with GDataXML
Also TCMXMLWriter is an opensource xmlgenerator :
I think a code like this work for your example :
NSString *contentFile = [[NSString alloc] initWithContentsOfFile:pathFile encoding:NSUTF8StringEncoding error:nil];
NSArray *lineFile = [contentFile componentsSeparatedByString:#"\n"];
NSMutableString *xmlFile = [[NSMutableString alloc] init];
For(int i = 3; i < lineFile.count; i++)//i = 3 for don't take the 3 first line
{
if ([((NSString *)[lineFile objectAtIndex:i]) rangedOfString:#"test"].location != NSNotFound)
{
xmlFile = [NSString stringWithFormat:#"%#<nameTag>%#</nameTag>", xmlFile, (NSString *)[lineFile objectAtIndex:i]];
}
else if ...
}
And save he nsstring in new file. Possible in loop to make by number like if i is multiple of 3 of 4 etc...
I am doing iPhone app dev. Usually, I put image(photo) files and some other configuration files in to supporting folder.
Can I update those files in supporting folder from server? If can, how to do it?
If not, can I pre-store the files which are need to upload into Document Folder and download newer files in document folder to replace older files?
we had the same problem in our current app. our final approach is this:
1) the assets we want to deliver with the app are stored inside a folder under Resources.
2) Plus there is an XML file telling us, which asset belongs where and how old it is (timestamp).
3) When the app starts for the first time, we copy all files (except the xml) from Rescources to the app's Cache folder:
// get the app's cache folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_cachesDirectory = [paths objectAtIndex:0];
_assetDirectory = [NSString stringWithFormat:#"%#/assets", _cachesDirectory];
// copy everything
_fmngr = [NSFileManager defaultManager];
- (void) copyAllFilesFromInitialFolder:(NSString*)path
{
NSArray *files = [_fmngr contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files)
{
if ([file isEqualToString:[NSString stringWithFormat:#"%#.xml", kDefaultXMLFileName]])
{
continue;
}
NSString *fpath = [NSString stringWithFormat:#"%#/%#", path, file];
BOOL isDir;
if ([_fmngr fileExistsAtPath:fpath isDirectory:&isDir])
{
if (isDir)
{
[self copyAllFilesFromInitialFolder:fpath];
}
else
{
NSString *relPath = [fpath substringFromIndex:[_initialLangDeviceContentPath length]+1];
NSString *fileName = [self convertFilePathToName:relPath];
NSString *tpath = [NSString stringWithFormat:#"%#/%#", _assetDirectory, fileName];
NSError *error;
BOOL success = [_fmngr copyItemAtPath:fpath toPath:tpath error:&error];
if (!success || error)
{
NSLog(#"INFO: copy %# to CACHES failed ... file may already be there.", file);
}
}
}
}
}
4) At the next start of the application, we check online if there are newer files on our update server. The XML from step 2) also resides on the server and has to be updated when JPGs/PNGs/... are updated/replaced on the server.
If nothing changed our PHP script returns a 304 "not modfied" - otherwise it'll output an updated version of the XML.
the PHP script looks something like this:
$doc = new DOMDocument();
#$doc->load($filename);
$xpath = new DOMXPath($doc);
$assets = $xpath->query('//asset');
if ($assets->length > 0)
{
foreach ($assets as $asset)
{
$assetPath = $asset->getAttribute('path');
if (file_exists($assetPath))
{
$atime = filemtime($assetPath);
$asset->setAttribute('modified', $atime);
}
else
{
// file not found - link broken
$asset->setAttribute('modified', '0');
}
}
}
$output = $doc->saveXML();
header('Content-type: text/xml');
echo $output;
The app downloads and parses the generated XML, comparing all modified values.
When there is an asset with a newer modified timestamp it is deleted locally and redownloaded. only after this check is completed the app starts - and you got the new assets on the device.
Hope this helps. We had some problems with the last modified attribute of the files we deliver with the app. When including the files into the app bundle and copying them at runtime, the files last modified is always the time of the first start of the app. sometimes you already updated some files on the server - but because the app thinks the files on the device are newer (because they were copied just now) they are not re-dowloaded from the server :(
so you can't work with the real file's attributes but have to include the actual file-date inside the XML file.
I want to check whether a string contains any of the substrings that I place in an array. Basically, I want to search the extensions of a file, and if the file is an "image", i want certain code to execute. The only way I can think of categorizing the file as an "Image" without downloading the file is through the substring in a string method. This is my code so far:
NSString *last5Chars = [folderName substringFromIndex: [folderName length] - 5];
NSRange textRangepdf;
textRangepdf =[last5Chars rangeOfString:#"pdf"];
if(textRangepdf.location != NSNotFound)
{
[self.itemType addObject:#"PDF.png"];
}
Is it possible to do this where I can check if last5Chars contains #"jpg" or #"gif" of #"png" etc...?? Thanks for helping!
NSString *fileName;
NSArray *imgExtArray; // put your file extensions in here
BOOL isImage = [imgExtArray containsObject:[fileName pathExtension]];
[folderName hasSuffix:#".jpg"] || [folderName hasSuffix:#".gif"]
obviously you can put it into a loop, if you have a whole arrayful.
Rather than mess about with ranges and suffixes, NSString has a method that treats an NSString as a path and returns an extension, it's called pathExtension.
Have a look in the NSString Documentation
Once you get the extension you can check it against whatever strings you want.
When I fetch the source of any web page, no matter the encoding I use, I always end up with &# - characters (such as © or ®) instead of the actual characters themselves. This goes for foreign characters as well (such as åäö in swedish), which I have to parse from "Å" and such).
I'm using
+stringWithContentsOfUrl: encoding: error;
to fetch the source and have tried several different encodings such as NSUTF8StringEncoding and NSASCIIStringEncoding, but nothing seems to affect the end result string.
Any ideas / tips / solution is greatly appreciated! I'd rather not have to implement the entire ASCII table and replace all occurrances of every character... Thanks in advance!
Regards
I'm using
+stringWithContentsOfUrl: encoding: error;
to fetch the source and have tried several different encodings such as NSUTF8StringEncoding and NSASCIIStringEncoding, but nothing seems to affect the end result string.
You're misunderstanding the purpose of that encoding: argument. The method needs to convert bytes into characters somehow; the encoding tells it what sequences of bytes describe which characters. You need to make sure the encoding matches that of the resource data.
The entity references are an SGML/XML thing. SGML and XML are not encodings; they are markup language syntaxes. stringWithContentsOfURL:encoding:error: and its cousins do not attempt to parse sequences of characters (syntax) in any way, which is what they would have to do to convert one sequence of characters (an entity reference) into a different one (the entity, in practice meaning single character, that is referenced).
You can convert the entity references to un-escaped characters using the CFXMLCreateStringByUnescapingEntities function. It takes a CFString, which an NSString is (toll-free bridging), and returns a CFString, which is an NSString.
Are you sure they originally are not in Å form? Try to view the source code in a browser first.
That really, really sucks. I wanted to convert it directly and the above solution isn't really a good one, so I just wrote my own ascii-table converter (static) class. Works as it should have worked natively (though I have to fill in the ascii table myself...)
Ideas for optimization? ("ASCII" is a static NSDictionary)
#implementation InternetHelper
+(NSString *)HTMLSourceFromUrlWithString:(NSString *)str convertASCII:(BOOL)state
{
NSURL *url = [NSURL URLWithString:str];
NSString *source = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
if (state)
source = [InternetHelper ConvertASCIICharactersInString:source];
return source;
}
+(NSString *)ConvertASCIICharactersInString:(NSString *)str
{
NSString *ret = [NSString stringWithString:str];
if (!ASCII)
{
NSString *path = [[NSBundle mainBundle] pathForResource:kASCIICharacterTableFilename ofType:kFileFormat];
ASCII = [[NSDictionary alloc] initWithContentsOfFile:path];
}
for (id key in ASCII)
{
ret = [ret stringByReplacingOccurrencesOfString:key withString:[ASCII objectForKey:key]];
}
return ret;
}
#end