strange NSString behaviour when used with [NSBundle mainBundle] pathForResource - iphone

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.

Related

remove specific characters from NSString

I wants to remove specific characters or group substring from NSString.
mean
NSString *str = #" hello I am #39;doing Parsing So $#39;I get many symbols in &my response";
I wants remove #39; and $#39; and & (Mostly these three strings comes in response)
output should be : hello I am doing Parsing So i get many symbols in my response
Side Question : I can't write & #39; without space here, because it converted in ' <-- this symbol. so i use $ in place of & in my question.
you should use [str stringByReplacingOccurrencesOfString:#"#39" withString:#""]
or you need replace strings of concrete format like "#number"?
try below code ,i think you got whatever you want simply change the charecterset,
NSString *string = #"hello I am #39;doing Parsing So $#39;I get many symbols in &my response";
NSCharacterSet *trim = [NSCharacterSet characterSetWithCharactersInString:#"#39;$&"];
NSString *result = [[string componentsSeparatedByCharactersInSet:trim] componentsJoinedByString:#""];
NSLog(#"%#", result);

Reading the first column data from CSV file and compare it with user input?

I am developing an app where users can upload a csv file to documents folder of app (I finished it). But I want to give a textfield to users in the app and ask them to enter a id number and this number will be checked with the uploaded csv files first column. If it matches then display an alert saying that its found a match or else it doesn't.
I use the following code but it checks only the first rows first column and not others... I call the function on button click...
NSString * pstrCSVFilePath= [[NSBundle mainBundle] pathForResource:#"CSVFile" ofType:#""]
NSString * pstrCSVFile= [NSString stringWithContentsOfFile:pstrCSVFilePath encoding:NSASCIIStringEncoding error:NULL];
NSArray * paRowsOfCSVFile= [pstrCSVFile componentsSeparatedByString:#"\n"];
NSArray * paColumnsOfRow;
NSString * pstrFirstColumn;
for(NSString * pstrRow in paRowsOfCSVFile)
{
paColumnsOfRow= [pstrRow componentsSeparatedByString:#","];
pstrFirstColumn= [paColumnsOfRow objectAtIndex:0];
if([pstrFirstColumn localizedCaseInsensitiveCompare:myTextField.text] == NSOrderedSame)
{
//Found the search string in the CSV file.
break;
}
}
Have you checked how many lines you've successfully split your input into? I'd guess that your input file is not linebreaked with \n but maybe \r...
If this is the problem, then you'll be interpreting the file as only having a single row. Check out this related answer for how to split into lines properly: How do I get each line from an NSString?. Depending on the version of iOS you're targeting, you can possibly use the method called out in the question itself.

Search for an array of substrings within a string

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.

iPhone SDK - stringWithContentsOfUrl ASCII characters in HTML source

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 "&Aring" 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

Open strings file from recource folder

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.