Lets say i have the following cstring
char array[1000];
How i can convert it to NSString and vice verse.
Thanks.
Apple's Developer Reference has a good article on this subject. Basically, you will do something like this:
NSString *stringFromUTFString = [[NSString alloc] initWithUTF8String:utf8String];
if the string is UTF8 encoded. Otherwise, you can use initWithCString:encoding: with which you can specify the encoding.
Here is a list of available string encodings.
Related
I'm parsing some HTML with NSXMLParser and it hits a parser error anytime it encounters an ampersand. I could filter out ampersands before I parse it, but I'd rather parse everything that's there.
It's giving me error 68, NSXMLParserNAMERequiredError: Name is required.
My best guess is that it's a character set issue. I'm a little fuzzy on the world of character sets, so I'm thinking my ignorance is biting me in the ass.
The source HTML uses charset iso-8859-1, so I'm using this code to initialize the Parser:
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] autorelease];
NSData *dataEncoded = [[dataString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES] autorelease];
NSXMLParser *theParser = [[NSXMLParser alloc] initWithData:dataEncoded];
Any ideas?
To the other posters: of course the XML is invalid... it's HTML!
You probably shouldn't be trying to use NSXMLParser for HTML, but rather libxml2
For a closer look at why, check out this article.
Are you sure you have valid XML? You are required to have special characters like & escaped, in the raw XML file you should see &
Encoding the Data through a NSString worked for me, anyway you are autoreleasing an object that was not allocated by yourself (dataUsingEncoding), so it crashes, the solution is :
NSString *dataString = [[NSString alloc] initWithData:data
encoding:NSISOLatin1StringEncoding];
NSData *dataEncoded = [dataString dataUsingEncoding:NSUTF8StringEncoding
allowLossyConversion:YES];
[dataString release];
NSXMLParser *theParser = [[NSXMLParser alloc] initWithData:dataEncoded];
I am accessing a plist file using the code below on a Cocoa with Objective-C application:
NSString *plistPath = [#"~/Library/Preferences/com.apple.mail.plist" stringByExpandingTildeInPath];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *item = [plistData valueForKeyPath:#"MailAccounts.AccountName"];
NSLog(#"Account: %#", [item objectAtIndex:2]);
Which essentially returns the email address of the user (we also read some other information on other plist files) so we can add it to the About dialog.
I need now to read this information from the same plist files using C, not Objective-C. The files are not text, they are binary encoded plist files. Is there any way to read those property files from C?
Can I call NSDictionary etc from C? How?
Thanks for the help.
Of course you realize that Objective C is an extension of C, but in general, when I'm using plain ol' C, I use Core Foundation functions and objects instead of Objective C methods.
To your specific question: CFDictionary is toll-free bridged to NSDictionary and CFBundle to NSBundle. You can easily call CoreFoundation from plain ol' C.
You can get what you want with something like:
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFDictionaryRef dictionaryRef = CFBundleGetInfoDictionary(mainBundle);
if(dictionaryRef)
{
CFArrayRef accountsItemsArrayRef = CFDictionaryGetValue(dictionaryRef, CFSTR("MailAccounts.AccountName");
if(accountsItemsArrayRef)
{
CFStringRef accountNameRef = (CFStringRef) CFArrayGetValueAtIndex(accountsItemsArrayRef, 2);
if(accountNameRef)
{
fprintf(stderr, "Account: %s", accountName.cStr());
}
}
}
I just typed this Core Foundation translation directly into this answer box and did no error or sanity checking, which you absolutely would need to do.
Here is a slightly older tutorial that explains a bit more.
Hope this helps to get you on the right path!
I have been attempting to use NSMutableArray's writeToFile:atomically:
But it has been pointed out to me that this approach is wrong: i.e. iPhone / Objective-C: NSMutableArray writeToFile won't write to file. Always returns NO
It looks like I'm going to have to read the guide on archiving that is referred to in one of the answers in the above link.
Would anyone care to share (or point me towards) some code that helps me accomplish this task?
The method, you've mentioned recursively validates that all the contained objects are property list objects before writing out the file.
Try this:
for (UIImage *image in arrayWithImages) {
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"Documents/%#", #"nameOfTheImage.png"]];
UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
}
Maybe you can use [UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES]; to write image as jpeg.
How can I restore a file with certain data. If a user enters a file in which he wants the data to be restored with, and that file is not there, it should be created with that data. This is all part of an encryption tool. So say I, the user, selects a file, and encrypts it. So I have my encrypted data. But now I need to move this encrypted data to a file, so that the user can take the file that contains the encrypted data, to decrypt, so that he gets his original file provided he entered the correct key.
Hopefully that was clear enough. All help is greatly appreciated.
Use NSFileManager to get (and possiby create) the file path for the data, then writeToFile: methods. Something like this:
- (void) saveCriteriaToFile: (NSArray *) criteria
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *supportDir = [[paths objectAtIndex:0] stringByAppendingPathComponent: #"StokerX"];
NSString *saveFilePath = [supportDir stringByAppendingPathComponent: kSavedNotificationsFile];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath: saveFilePath] == NO)
{
[fileManager createDirectoryAtPath: supportDir withIntermediateDirectories:YES attributes:nil error:nil];
}
[criteria writeToFile:saveFilePath atomically:YES];
}
This one is writing an NSArray object to a pilist, but you do it almost the same with an NSData object.
I fixed my problem by using NSHomeDirectory instead of hardcoding the path. Thanks though for the help.
I'm working through the Stanford iPhone podcasts and have some basic questions.
The first: why is there no easy string concatenation? (or am I just missing it?)
I needed help with the NSLog below, and have no idea what it's currently doing (the %# part). Do you just substitute those in wherever you need concatenation, and then comma separate the values at the end?
NSString *path = #"~";
NSString *absolutePath = [path stringByExpandingTildeInPath];
NSLog(#"My home folder is at '%#'", absolutePath);
whereas with any other programing language I'd have done it like this:
NSLog(#"My home folder is at " + absolutePath);
Thanks! (Additionally, any good guides/references for someone familiar with Java/C#/etc style syntax transitioning to Objective-C?)
%# is a placeholder in a format string, for a NSString instance.
When you do something like:
NSLog(#"My home folder is at '%#'", absolutePath);
You are telling NSLog to replace the %# placeholder with the string called absolutePath.
Likewise, if you put more placeholders, you can specify more values to replace those placeholders like this:
NSString *absolutePath = #"/home/whatever";
NSLog(#"My home #%d folder is at '%#'", 5, absolutePath);
Will print:
My home #5 is at /home/whatever
An easy way to do string concatenation:
NSString *s1 = #"Hello, ";
NSString *s2 = #"world.";
NSString *s = [NSString stringWithFormat:#"%#%#", s1, s2];
// s will be "Hello, world."
You can't have a + sign as a string concatenate operator, since there is no operator overloading in Objective-C.
Hope it helps.
That is a string format specifier. Basically it allows you to specify a placeholder in the string and the values that are to be inserted into the placeholder's spot. The link I reference above lists the different notations for the placeholders and each placeholder's specific format.
It's just like C#'s String.Format method:
NSLog(String.Format("My home folder is at '{0}'", absolutePath));
You can use NSString +stringWithFormat to do concatenation:
NSString* a = // ...
NSString* b = // ...
NSString* a_concatenated_with_b = [NSString stringWithFormat:#"%#%#",a,b];
The reason for the "%#" is that the string formatting is based off of and extends the printf format strings syntax. These functions take a variable number of arguments, and anything beginning with a percent sign (%) is interpreted as a place holder. The subsequent characters determine the type of the place holder. The standard printf does not use "%#", and since "#" is the symbol commonly used for things that Objective-C adds to the C language, it makes sense that the "#" would symbolize "an Objective-C object".
There is no automatic concatentation using the plus sign (+), because NSString* is a pointer type, and Objective-C is a strict superset of C, and so, consequently, adding to an NSString* object does pointer manipulation. Objective-C does not have any operator overloading feature as in the C++ language.
Also, %# is fairly versatile, as it actually inserts the result of the argument's description method into the result string. For NSString, that's the string's value, other classes can provide useful overrides. Similar to toString in Java, for example.